Merge from mozilla-central.

This commit is contained in:
Jan de Mooij 2013-02-25 15:11:44 +01:00
commit 5bc026e40f
2348 changed files with 68180 additions and 9066 deletions

View File

@ -75,7 +75,7 @@ protected:
/**
* The document accessible reference owning this queue.
*/
nsRefPtr<DocAccessible> mDocument;
DocAccessible* mDocument;
/**
* Pending events array. Don't make this an nsAutoTArray; we use

View File

@ -54,7 +54,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(NotificationController)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(NotificationController)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHangingChildDocuments)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContentInsertions)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvents)

View File

@ -1757,6 +1757,7 @@ DocAccessible::UpdateTree(Accessible* aContainer, nsIContent* aChildNode,
// XXX: since select change insertion point of option contained by optgroup
// then we need to have special processing for them (bug 690417).
if (!aIsInsert && aChildNode->IsHTML(nsGkAtoms::optgroup) &&
aContainer->GetContent() &&
aContainer->GetContent()->IsHTML(nsGkAtoms::select)) {
for (nsIContent* optContent = aChildNode->GetFirstChild(); optContent;
optContent = optContent->GetNextSibling()) {

View File

@ -1,30 +1,30 @@
The files which make up the SDK are developed by Mozilla and licensed
under the MPL 2.0 (http://mozilla.org/MPL/2.0/), with the exception of the
components listed below, which are made available by their authors under
the licenses listed alongside.
syntaxhighlighter
------------------
doc/static-files/syntaxhighlighter
Made available under the MIT license.
jQuery
------
examples/reddit-panel/data/jquery-1.4.4.min.js
examples/annotator/data/jquery-1.4.2.min.js
Made available under the MIT license.
simplejson
----------
python-lib/simplejson
Made available under the MIT license.
Python Markdown
---------------
python-lib/markdown
Made available under the BSD license.
LibraryDetector
---------------
examples/library-detector/data/library-detector.js
Made available under the MIT license.
The files which make up the SDK are developed by Mozilla and licensed
under the MPL 2.0 (http://mozilla.org/MPL/2.0/), with the exception of the
components listed below, which are made available by their authors under
the licenses listed alongside.
syntaxhighlighter
------------------
doc/static-files/syntaxhighlighter
Made available under the MIT license.
jQuery
------
examples/reddit-panel/data/jquery-1.4.4.min.js
examples/annotator/data/jquery-1.4.2.min.js
Made available under the MIT license.
simplejson
----------
python-lib/simplejson
Made available under the MIT license.
Python Markdown
---------------
python-lib/markdown
Made available under the BSD license.
LibraryDetector
---------------
examples/library-detector/data/library-detector.js
Made available under the MIT license.

View File

@ -1,45 +1,45 @@
Add-on SDK README
==================
Before proceeding, please make sure you've installed Python 2.5,
2.6, or 2.7 (if it's not already on your system):
http://python.org/download/
Note that Python 3.0 and 3.1 are not supported in this release.
For Windows users, MozillaBuild (https://wiki.mozilla.org/MozillaBuild)
will install the correct version of Python and the MSYS package, which
will make it easier to work with the SDK.
To get started, first enter the same directory that this README file
is in (the SDK's root directory) using a shell program. On Unix systems
or on Windows with MSYS, you can execute the following command:
source bin/activate
Windows users using cmd.exe should instead run:
bin\activate.bat
Then run:
cfx docs
This should start a documentation server and open a web browser
with further instructions.
If you get an error when running cfx or have any other problems getting
started, see the "Troubleshooting" guide at:
https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/tutorials/troubleshooting.html
Bugs
-------
* file a bug: https://bugzilla.mozilla.org/enter_bug.cgi?product=Add-on%20SDK
Style Guidelines
--------------------
Add-on SDK README
==================
Before proceeding, please make sure you've installed Python 2.5,
2.6, or 2.7 (if it's not already on your system):
http://python.org/download/
Note that Python 3.0 and 3.1 are not supported in this release.
For Windows users, MozillaBuild (https://wiki.mozilla.org/MozillaBuild)
will install the correct version of Python and the MSYS package, which
will make it easier to work with the SDK.
To get started, first enter the same directory that this README file
is in (the SDK's root directory) using a shell program. On Unix systems
or on Windows with MSYS, you can execute the following command:
source bin/activate
Windows users using cmd.exe should instead run:
bin\activate.bat
Then run:
cfx docs
This should start a documentation server and open a web browser
with further instructions.
If you get an error when running cfx or have any other problems getting
started, see the "Troubleshooting" guide at:
https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/tutorials/troubleshooting.html
Bugs
-------
* file a bug: https://bugzilla.mozilla.org/enter_bug.cgi?product=Add-on%20SDK
Style Guidelines
--------------------
* https://github.com/mozilla/addon-sdk/wiki/Coding-style-guide

View File

@ -19,6 +19,13 @@ const resourceHandler = ioService.getProtocolHandler('resource').
const systemPrincipal = CC('@mozilla.org/systemprincipal;1', 'nsIPrincipal')();
const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1'].
getService(Ci.mozIJSSubScriptLoader);
const prefService = Cc['@mozilla.org/preferences-service;1'].
getService(Ci.nsIPrefService);
const appInfo = Cc["@mozilla.org/xre/app-info;1"].
getService(Ci.nsIXULAppInfo);
const vc = Cc["@mozilla.org/xpcom/version-comparator;1"].
getService(Ci.nsIVersionComparator);
const REASON = [ 'unknown', 'startup', 'shutdown', 'enable', 'disable',
'install', 'uninstall', 'upgrade', 'downgrade' ];
@ -120,19 +127,54 @@ function startup(data, reasonCode) {
if (name == 'addon-sdk')
paths['tests/'] = prefixURI + name + '/tests/';
// Maps sdk module folders to their resource folder
paths['sdk/'] = prefixURI + 'addon-sdk/lib/sdk/';
paths['toolkit/'] = prefixURI + 'addon-sdk/lib/toolkit/';
// test.js is usually found in root commonjs or SDK_ROOT/lib/ folder,
// so that it isn't shipped in the xpi. Keep a copy of it in sdk/ folder
// until we no longer support SDK modules in XPI:
paths['test'] = prefixURI + 'addon-sdk/lib/sdk/test.js';
// Starting with Firefox 21.0a1, we start using modules shipped into firefox
// Still allow using modules from the xpi if the manifest tell us to do so.
// And only try to look for sdk modules in xpi if the xpi actually ship them
if (options['is-sdk-bundled'] &&
(vc.compare(appInfo.version, '21.0a1') < 0 ||
options['force-use-bundled-sdk'])) {
// Maps sdk module folders to their resource folder
paths[''] = prefixURI + 'addon-sdk/lib/';
// test.js is usually found in root commonjs or SDK_ROOT/lib/ folder,
// so that it isn't shipped in the xpi. Keep a copy of it in sdk/ folder
// until we no longer support SDK modules in XPI:
paths['test'] = prefixURI + 'addon-sdk/lib/sdk/test.js';
}
// Retrieve list of module folder overloads based on preferences in order to
// eventually used a local modules instead of files shipped into Firefox.
let branch = prefService.getBranch('extensions.modules.' + id + '.path');
paths = branch.getChildList('', {}).reduce(function (result, name) {
// Allows overloading of any sub folder by replacing . by / in pref name
let path = name.substr(1).split('.').join('/');
// Only accept overloading folder by ensuring always ending with `/`
if (path) path += '/';
let fileURI = branch.getCharPref(name);
// Maps the given file:// URI to a resource:// in order to avoid various
// failure that happens with file:// URI and be close to production env
let resourcesURI = ioService.newURI(fileURI, null, null);
let resName = 'extensions.modules.' + domain + '.commonjs.path' + name;
resourceHandler.setSubstitution(resName, resourcesURI);
result[path] = 'resource://' + resName + '/';
return result;
}, paths);
// Make version 2 of the manifest
let manifest = options.manifest;
// Import `cuddlefish.js` module using a Sandbox and bootstrap loader.
let cuddlefishURI = prefixURI + options.loader;
let cuddlefishPath = 'loader/cuddlefish.js';
let cuddlefishURI = 'resource://gre/modules/commonjs/sdk/' + cuddlefishPath;
if (paths['sdk/']) { // sdk folder has been overloaded
// (from pref, or cuddlefish is still in the xpi)
cuddlefishURI = paths['sdk/'] + cuddlefishPath;
}
else if (paths['']) { // root modules folder has been overloaded
cuddlefishURI = paths[''] + 'sdk/' + cuddlefishPath;
}
cuddlefishSandbox = loadSandbox(cuddlefishURI);
let cuddlefish = cuddlefishSandbox.exports;

View File

@ -1,364 +1,364 @@
#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import signal
import threading
import urllib2, urllib
import zipfile
import tarfile
import subprocess
import optparse
import sys, re
#import win32api
class SDK:
def __init__(self):
try:
# Take the current working directory
self.default_path = os.getcwd()
if sys.platform == "win32":
self.mswindows = True
else:
self.mswindows = False
# Take the default home path of the user.
home = os.path.expanduser('~')
# The following are the parameters that can be used to pass a dynamic URL, a specific path or a binry. The binary is not used yet. It will be used in version 2.0
# If a dynamic path is to be mentioned, it should start with a '/'. For eg. "/Desktop"
parser = optparse.OptionParser()
parser.add_option('-u', '--url', dest = 'url', default = 'https://ftp.mozilla.org/pub/mozilla.org/labs/jetpack/addon-sdk-latest.zip')
parser.add_option('-p', '--path', dest = 'path', default = self.default_path)
parser.add_option('-b', '--binary', dest = 'binary')#, default='/Applications/Firefox.app')
(options, args) = parser.parse_args()
# Get the URL from the parameter
self.link = options.url
# Set the base path for the user. If the user supplies the path, use the home variable as well. Else, take the default path of this script as the installation directory.
if options.path!=self.default_path:
if self.mswindows:
self.base_path = home + str(options.path).strip() + '\\'
else:
self.base_path = home + str(options.path).strip() + '/'
else:
if self.mswindows:
self.base_path = str(options.path).strip() + '\\'
else:
self.base_path = str(options.path).strip() + '/'
assert ' ' not in self.base_path, "You cannot have a space in your home path. Please remove the space before you continue."
print('Your Base path is =' + self.base_path)
# This assignment is not used in this program. It will be used in version 2 of this script.
self.bin = options.binary
# if app or bin is empty, dont pass anything
# Search for the .zip file or tarball file in the URL.
i = self.link.rfind('/')
self.fname = self.link[i+1:]
z = re.search('zip',self.fname,re.I)
g = re.search('gz',self.fname,re.I)
if z:
print 'zip file present in the URL.'
self.zip = True
self.gz = False
elif g:
print 'gz file present in the URL'
self.gz = True
self.zip = False
else:
print 'zip/gz file not present. Check the URL.'
return
print("File name is =" + self.fname)
# Join the base path and the zip/tar file name to crate a complete Local file path.
self.fpath = self.base_path + self.fname
print('Your local file path will be=' + self.fpath)
except AssertionError, e:
print e.args[0]
sys.exit(1)
# Download function - to download the SDK from the URL to the local machine.
def download(self,url,fpath,fname):
try:
# Start the download
print("Downloading...Please be patient!")
urllib.urlretrieve(url,filename = fname)
print('Download was successful.')
except ValueError: # Handles broken URL errors.
print 'The URL is ether broken or the file does not exist. Please enter the correct URL.'
raise
except urllib2.URLError: # Handles URL errors
print '\nURL not correct. Check again!'
raise
# Function to extract the downloaded zipfile.
def extract(self, zipfilepath, extfile):
try:
# Timeout is set to 30 seconds.
timeout = 30
# Change the directory to the location of the zip file.
try:
os.chdir(zipfilepath)
except OSError:
# Will reach here if zip file doesnt exist
print 'O/S Error:' + zipfilepath + 'does not exist'
raise
# Get the folder name of Jetpack to get the exact version number.
if self.zip:
try:
f = zipfile.ZipFile(extfile, "r")
except IOError as (errno, strerror): # Handles file errors
print "I/O error - Cannot perform extract operation: {1}".format(errno, strerror)
raise
list = f.namelist()[0]
temp_name = list.split('/')
print('Folder Name= ' +temp_name[0])
self.folder_name = temp_name[0]
elif self.gz:
try:
f = tarfile.open(extfile,'r')
except IOError as (errno, strerror): # Handles file errors
print "I/O error - Cannot perform extract operation: {1}".format(errno, strerror)
raise
list = f.getnames()[0]
temp_name = list.split('/')
print('Folder Name= ' +temp_name[0])
self.folder_name = temp_name[0]
print ('Starting to Extract...')
# Timeout code. The subprocess.popen exeutes the command and the thread waits for a timeout. If the process does not finish within the mentioned-
# timeout, the process is killed.
kill_check = threading.Event()
if self.zip:
# Call the command to unzip the file.
if self.mswindows:
zipfile.ZipFile.extractall(f)
else:
p = subprocess.Popen('unzip '+extfile, stdout=subprocess.PIPE, shell=True)
pid = p.pid
elif self.gz:
# Call the command to untar the file.
if self.mswindows:
tarfile.TarFile.extractall(f)
else:
p = subprocess.Popen('tar -xf '+extfile, stdout=subprocess.PIPE, shell=True)
pid = p.pid
#No need to handle for windows because windows automatically replaces old files with new files. It does not ask the user(as it does in Mac/Unix)
if self.mswindows==False:
watch = threading.Timer(timeout, kill_process, args=(pid, kill_check, self.mswindows ))
watch.start()
(stdout, stderr) = p.communicate()
watch.cancel() # if it's still waiting to run
success = not kill_check.isSet()
# Abort process if process fails.
if not success:
raise RuntimeError
kill_check.clear()
print('Extraction Successful.')
except RuntimeError:
print "Ending the program"
sys.exit(1)
except:
print "Error during file extraction: ", sys.exc_info()[0]
raise
# Function to run the cfx testall comands and to make sure the SDK is not broken.
def run_testall(self, home_path, folder_name):
try:
timeout = 500
self.new_dir = home_path + folder_name
try:
os.chdir(self.new_dir)
except OSError:
# Will reach here if the jetpack 0.X directory doesnt exist
print 'O/S Error: Jetpack directory does not exist at ' + self.new_dir
raise
print '\nStarting tests...'
# Timeout code. The subprocess.popen exeutes the command and the thread waits for a timeout. If the process does not finish within the mentioned-
# timeout, the process is killed.
kill_check = threading.Event()
# Set the path for the logs. They will be in the parent directory of the Jetpack SDK.
log_path = home_path + 'tests.log'
# Subprocess call to set up the jetpack environment and to start the tests. Also sends the output to a log file.
if self.bin != None:
if self.mswindows:
p = subprocess.Popen("bin\\activate && cfx testall -a firefox -b \"" + self.bin + "\"" , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout,stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx testall -a firefox -b ' + self.bin , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout,stderr) = p.communicate()
elif self.bin == None:
if self.mswindows:
p=subprocess.Popen('bin\\activate && cfx testall -a firefox > '+log_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout,stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx testall -a firefox > '+log_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout,stderr) = p.communicate()
#Write the output to log file
f=open(log_path,"w")
f.write(stdout+stderr)
f.close()
#Watchdog for timeout process
if self.mswindows:
watch = threading.Timer(timeout, kill_process, args=(proc_handle, kill_check, self.mswindows))
else:
watch = threading.Timer(timeout, kill_process, args=(pid, kill_check, self.mswindows))
watch.start()
watch.cancel() # if it's still waiting to run
success = not kill_check.isSet()
if not success:
raise RuntimeError
kill_check.clear()
if p.returncode!=0:
print('\nAll tests were not successful. Check the test-logs in the jetpack directory.')
result_sdk(home_path)
#sys.exit(1)
raise RuntimeError
else:
ret_code=result_sdk(home_path)
if ret_code==0:
print('\nAll tests were successful. Yay \o/ . Running a sample package test now...')
else:
print ('\nThere were errors during the tests.Take a look at logs')
raise RuntimeError
except RuntimeError:
print "Ending the program"
sys.exit(1)
except:
print "Error during the testall command execution:", sys.exc_info()[0]
raise
def package(self, example_dir):
try:
timeout = 30
print '\nNow Running packaging tests...'
kill_check = threading.Event()
# Set the path for the example logs. They will be in the parent directory of the Jetpack SDK.
exlog_path = example_dir + 'test-example.log'
# Subprocess call to test the sample example for packaging.
if self.bin!=None:
if self.mswindows:
p = subprocess.Popen('bin\\activate && cfx run --pkgdir examples\\reading-data --static-args="{\\"quitWhenDone\\":true}" -b \"" + self.bin + "\"' , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout, stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx run --pkgdir examples/reading-data --static-args=\'{\"quitWhenDone\":true}\' -b ' + self.bin , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout, stderr) = p.communicate()
elif self.bin==None:
if self.mswindows:
p = subprocess.Popen('bin\\activate && cfx run --pkgdir examples\\reading-data --static-args="{\\"quitWhenDone\\":true}"', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout, stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx run --pkgdir examples/reading-data --static-args=\'{\"quitWhenDone\":true}\' ', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout, stderr) = p.communicate()
#Write the output to log file
f=open(exlog_path,"w")
f.write(stdout+stderr)
f.close()
#Watch dog for timeout process
if self.mswindows:
watch = threading.Timer(timeout, kill_process, args=(proc_handle, kill_check, self.mswindows))
else:
watch = threading.Timer(timeout, kill_process, args=(pid, kill_check, self.mswindows))
watch.start()
watch.cancel() # if it's still waiting to run
success = not kill_check.isSet()
if not success:
raise RuntimeError
kill_check.clear()
if p.returncode != 0:
print('\nSample tests were not executed correctly. Check the test-example log in jetpack diretory.')
result_example(example_dir)
raise RuntimeError
else:
ret_code=result_example(example_dir)
if ret_code==0:
print('\nAll tests pass. The SDK is working! Yay \o/')
else:
print ('\nTests passed with warning.Take a look at logs')
sys.exit(1)
except RuntimeError:
print "Ending program"
sys.exit(1)
except:
print "Error during running sample tests:", sys.exc_info()[0]
raise
def result_sdk(sdk_dir):
log_path = sdk_dir + 'tests.log'
print 'Results are logged at:' + log_path
try:
f = open(log_path,'r')
# Handles file errors
except IOError :
print 'I/O error - Cannot open test log at ' + log_path
raise
for line in reversed(open(log_path).readlines()):
if line.strip()=='FAIL':
print ('\nOverall result - FAIL. Look at the test log at '+log_path)
return 1
return 0
def result_example(sdk_dir):
exlog_path = sdk_dir + 'test-example.log'
print 'Sample test results are logged at:' + exlog_path
try:
f = open(exlog_path,'r')
# Handles file errors
except IOError :
print 'I/O error - Cannot open sample test log at ' + exlog_path
raise
#Read the file in reverse and check for the keyword 'FAIL'.
for line in reversed(open(exlog_path).readlines()):
if line.strip()=='FAIL':
print ('\nOverall result for Sample tests - FAIL. Look at the test log at '+exlog_path)
return 1
return 0
def kill_process(process, kill_check, mswindows):
print '\nProcess Timedout. Killing the process. Please Rerun this script.'
if mswindows:
win32api.TerminateProcess(process, -1)
else:
os.kill(process, signal.SIGKILL)
kill_check.set()# tell the main routine to kill. Used SIGKILL to hard kill the process.
return
if __name__ == "__main__":
obj = SDK()
obj.download(obj.link,obj.fpath,obj.fname)
obj.extract(obj.base_path,obj.fname)
obj.run_testall(obj.base_path,obj.folder_name)
obj.package(obj.base_path)
#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import signal
import threading
import urllib2, urllib
import zipfile
import tarfile
import subprocess
import optparse
import sys, re
#import win32api
class SDK:
def __init__(self):
try:
# Take the current working directory
self.default_path = os.getcwd()
if sys.platform == "win32":
self.mswindows = True
else:
self.mswindows = False
# Take the default home path of the user.
home = os.path.expanduser('~')
# The following are the parameters that can be used to pass a dynamic URL, a specific path or a binry. The binary is not used yet. It will be used in version 2.0
# If a dynamic path is to be mentioned, it should start with a '/'. For eg. "/Desktop"
parser = optparse.OptionParser()
parser.add_option('-u', '--url', dest = 'url', default = 'https://ftp.mozilla.org/pub/mozilla.org/labs/jetpack/addon-sdk-latest.zip')
parser.add_option('-p', '--path', dest = 'path', default = self.default_path)
parser.add_option('-b', '--binary', dest = 'binary')#, default='/Applications/Firefox.app')
(options, args) = parser.parse_args()
# Get the URL from the parameter
self.link = options.url
# Set the base path for the user. If the user supplies the path, use the home variable as well. Else, take the default path of this script as the installation directory.
if options.path!=self.default_path:
if self.mswindows:
self.base_path = home + str(options.path).strip() + '\\'
else:
self.base_path = home + str(options.path).strip() + '/'
else:
if self.mswindows:
self.base_path = str(options.path).strip() + '\\'
else:
self.base_path = str(options.path).strip() + '/'
assert ' ' not in self.base_path, "You cannot have a space in your home path. Please remove the space before you continue."
print('Your Base path is =' + self.base_path)
# This assignment is not used in this program. It will be used in version 2 of this script.
self.bin = options.binary
# if app or bin is empty, dont pass anything
# Search for the .zip file or tarball file in the URL.
i = self.link.rfind('/')
self.fname = self.link[i+1:]
z = re.search('zip',self.fname,re.I)
g = re.search('gz',self.fname,re.I)
if z:
print 'zip file present in the URL.'
self.zip = True
self.gz = False
elif g:
print 'gz file present in the URL'
self.gz = True
self.zip = False
else:
print 'zip/gz file not present. Check the URL.'
return
print("File name is =" + self.fname)
# Join the base path and the zip/tar file name to crate a complete Local file path.
self.fpath = self.base_path + self.fname
print('Your local file path will be=' + self.fpath)
except AssertionError, e:
print e.args[0]
sys.exit(1)
# Download function - to download the SDK from the URL to the local machine.
def download(self,url,fpath,fname):
try:
# Start the download
print("Downloading...Please be patient!")
urllib.urlretrieve(url,filename = fname)
print('Download was successful.')
except ValueError: # Handles broken URL errors.
print 'The URL is ether broken or the file does not exist. Please enter the correct URL.'
raise
except urllib2.URLError: # Handles URL errors
print '\nURL not correct. Check again!'
raise
# Function to extract the downloaded zipfile.
def extract(self, zipfilepath, extfile):
try:
# Timeout is set to 30 seconds.
timeout = 30
# Change the directory to the location of the zip file.
try:
os.chdir(zipfilepath)
except OSError:
# Will reach here if zip file doesnt exist
print 'O/S Error:' + zipfilepath + 'does not exist'
raise
# Get the folder name of Jetpack to get the exact version number.
if self.zip:
try:
f = zipfile.ZipFile(extfile, "r")
except IOError as (errno, strerror): # Handles file errors
print "I/O error - Cannot perform extract operation: {1}".format(errno, strerror)
raise
list = f.namelist()[0]
temp_name = list.split('/')
print('Folder Name= ' +temp_name[0])
self.folder_name = temp_name[0]
elif self.gz:
try:
f = tarfile.open(extfile,'r')
except IOError as (errno, strerror): # Handles file errors
print "I/O error - Cannot perform extract operation: {1}".format(errno, strerror)
raise
list = f.getnames()[0]
temp_name = list.split('/')
print('Folder Name= ' +temp_name[0])
self.folder_name = temp_name[0]
print ('Starting to Extract...')
# Timeout code. The subprocess.popen exeutes the command and the thread waits for a timeout. If the process does not finish within the mentioned-
# timeout, the process is killed.
kill_check = threading.Event()
if self.zip:
# Call the command to unzip the file.
if self.mswindows:
zipfile.ZipFile.extractall(f)
else:
p = subprocess.Popen('unzip '+extfile, stdout=subprocess.PIPE, shell=True)
pid = p.pid
elif self.gz:
# Call the command to untar the file.
if self.mswindows:
tarfile.TarFile.extractall(f)
else:
p = subprocess.Popen('tar -xf '+extfile, stdout=subprocess.PIPE, shell=True)
pid = p.pid
#No need to handle for windows because windows automatically replaces old files with new files. It does not ask the user(as it does in Mac/Unix)
if self.mswindows==False:
watch = threading.Timer(timeout, kill_process, args=(pid, kill_check, self.mswindows ))
watch.start()
(stdout, stderr) = p.communicate()
watch.cancel() # if it's still waiting to run
success = not kill_check.isSet()
# Abort process if process fails.
if not success:
raise RuntimeError
kill_check.clear()
print('Extraction Successful.')
except RuntimeError:
print "Ending the program"
sys.exit(1)
except:
print "Error during file extraction: ", sys.exc_info()[0]
raise
# Function to run the cfx testall comands and to make sure the SDK is not broken.
def run_testall(self, home_path, folder_name):
try:
timeout = 500
self.new_dir = home_path + folder_name
try:
os.chdir(self.new_dir)
except OSError:
# Will reach here if the jetpack 0.X directory doesnt exist
print 'O/S Error: Jetpack directory does not exist at ' + self.new_dir
raise
print '\nStarting tests...'
# Timeout code. The subprocess.popen exeutes the command and the thread waits for a timeout. If the process does not finish within the mentioned-
# timeout, the process is killed.
kill_check = threading.Event()
# Set the path for the logs. They will be in the parent directory of the Jetpack SDK.
log_path = home_path + 'tests.log'
# Subprocess call to set up the jetpack environment and to start the tests. Also sends the output to a log file.
if self.bin != None:
if self.mswindows:
p = subprocess.Popen("bin\\activate && cfx testall -a firefox -b \"" + self.bin + "\"" , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout,stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx testall -a firefox -b ' + self.bin , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout,stderr) = p.communicate()
elif self.bin == None:
if self.mswindows:
p=subprocess.Popen('bin\\activate && cfx testall -a firefox > '+log_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout,stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx testall -a firefox > '+log_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout,stderr) = p.communicate()
#Write the output to log file
f=open(log_path,"w")
f.write(stdout+stderr)
f.close()
#Watchdog for timeout process
if self.mswindows:
watch = threading.Timer(timeout, kill_process, args=(proc_handle, kill_check, self.mswindows))
else:
watch = threading.Timer(timeout, kill_process, args=(pid, kill_check, self.mswindows))
watch.start()
watch.cancel() # if it's still waiting to run
success = not kill_check.isSet()
if not success:
raise RuntimeError
kill_check.clear()
if p.returncode!=0:
print('\nAll tests were not successful. Check the test-logs in the jetpack directory.')
result_sdk(home_path)
#sys.exit(1)
raise RuntimeError
else:
ret_code=result_sdk(home_path)
if ret_code==0:
print('\nAll tests were successful. Yay \o/ . Running a sample package test now...')
else:
print ('\nThere were errors during the tests.Take a look at logs')
raise RuntimeError
except RuntimeError:
print "Ending the program"
sys.exit(1)
except:
print "Error during the testall command execution:", sys.exc_info()[0]
raise
def package(self, example_dir):
try:
timeout = 30
print '\nNow Running packaging tests...'
kill_check = threading.Event()
# Set the path for the example logs. They will be in the parent directory of the Jetpack SDK.
exlog_path = example_dir + 'test-example.log'
# Subprocess call to test the sample example for packaging.
if self.bin!=None:
if self.mswindows:
p = subprocess.Popen('bin\\activate && cfx run --pkgdir examples\\reading-data --static-args="{\\"quitWhenDone\\":true}" -b \"" + self.bin + "\"' , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout, stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx run --pkgdir examples/reading-data --static-args=\'{\"quitWhenDone\":true}\' -b ' + self.bin , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout, stderr) = p.communicate()
elif self.bin==None:
if self.mswindows:
p = subprocess.Popen('bin\\activate && cfx run --pkgdir examples\\reading-data --static-args="{\\"quitWhenDone\\":true}"', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
proc_handle = p._handle
(stdout, stderr) = p.communicate()
else:
p = subprocess.Popen('. bin/activate; cfx run --pkgdir examples/reading-data --static-args=\'{\"quitWhenDone\":true}\' ', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
pid = p.pid
(stdout, stderr) = p.communicate()
#Write the output to log file
f=open(exlog_path,"w")
f.write(stdout+stderr)
f.close()
#Watch dog for timeout process
if self.mswindows:
watch = threading.Timer(timeout, kill_process, args=(proc_handle, kill_check, self.mswindows))
else:
watch = threading.Timer(timeout, kill_process, args=(pid, kill_check, self.mswindows))
watch.start()
watch.cancel() # if it's still waiting to run
success = not kill_check.isSet()
if not success:
raise RuntimeError
kill_check.clear()
if p.returncode != 0:
print('\nSample tests were not executed correctly. Check the test-example log in jetpack diretory.')
result_example(example_dir)
raise RuntimeError
else:
ret_code=result_example(example_dir)
if ret_code==0:
print('\nAll tests pass. The SDK is working! Yay \o/')
else:
print ('\nTests passed with warning.Take a look at logs')
sys.exit(1)
except RuntimeError:
print "Ending program"
sys.exit(1)
except:
print "Error during running sample tests:", sys.exc_info()[0]
raise
def result_sdk(sdk_dir):
log_path = sdk_dir + 'tests.log'
print 'Results are logged at:' + log_path
try:
f = open(log_path,'r')
# Handles file errors
except IOError :
print 'I/O error - Cannot open test log at ' + log_path
raise
for line in reversed(open(log_path).readlines()):
if line.strip()=='FAIL':
print ('\nOverall result - FAIL. Look at the test log at '+log_path)
return 1
return 0
def result_example(sdk_dir):
exlog_path = sdk_dir + 'test-example.log'
print 'Sample test results are logged at:' + exlog_path
try:
f = open(exlog_path,'r')
# Handles file errors
except IOError :
print 'I/O error - Cannot open sample test log at ' + exlog_path
raise
#Read the file in reverse and check for the keyword 'FAIL'.
for line in reversed(open(exlog_path).readlines()):
if line.strip()=='FAIL':
print ('\nOverall result for Sample tests - FAIL. Look at the test log at '+exlog_path)
return 1
return 0
def kill_process(process, kill_check, mswindows):
print '\nProcess Timedout. Killing the process. Please Rerun this script.'
if mswindows:
win32api.TerminateProcess(process, -1)
else:
os.kill(process, signal.SIGKILL)
kill_check.set()# tell the main routine to kill. Used SIGKILL to hard kill the process.
return
if __name__ == "__main__":
obj = SDK()
obj.download(obj.link,obj.fpath,obj.fname)
obj.extract(obj.base_path,obj.fname)
obj.run_testall(obj.base_path,obj.folder_name)
obj.package(obj.base_path)

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.1" id="svg2997" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" viewBox="-0.5 -0.5 200 200" overflow="visible" enable-background="new -0.5 -0.5 200 200" xml:space="preserve">
<path id="path85" fill="#FFFFFF" d="M-2559.936,6359.65c19.127,26.489,46.371,47.744,80.988,44.707 C-2479.339,6371.648-2523.898,6352.641-2559.936,6359.65z"/>

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -139,6 +139,11 @@ opened in the first tab in that window. This is an optional property.
If present and true, the new tab will be opened to the right of the active tab
and will not be active. This is an optional property.
@prop isPrivate {boolean}
Boolean which will determine if a private tab should be opened.
Private browsing mode must be supported in order to do this.
See the [private-browsing](modules/sdk/private-browsing.html) documentation for more information.
@prop [isPinned] {boolean}
If present and true, then the new tab will be pinned as an
[app tab](http://support.mozilla.com/en-US/kb/what-are-app-tabs).

View File

@ -118,6 +118,11 @@ If the only option being used is `url`, then a bare string URL can be passed to
String URL to be opened in the new window.
This is a required property.
@prop isPrivate {boolean}
Boolean which will determine if a private window should be opened.
Private browsing mode must be supported in order to do this.
See the [private-browsing](modules/sdk/private-browsing.html) documentation for more information.
@prop [onOpen] {function}
A callback function that is called when the window has opened. This does not
mean that the URL content has loaded, only that the window itself is fully

View File

@ -13,6 +13,7 @@ function Options(options) {
url: { is: ["string"] },
inBackground: { is: ["undefined", "boolean"] },
isPinned: { is: ["undefined", "boolean"] },
isPrivate: { is: ["undefined", "boolean"] },
onOpen: { is: ["undefined", "function"] },
onClose: { is: ["undefined", "function"] },
onReady: { is: ["undefined", "function"] },

View File

@ -4,19 +4,61 @@
'use strict';
// TODO: BUG 792670 - remove dependency below
const { browserWindows } = require('../windows');
const { browserWindows: windows } = require('../windows');
const { tabs } = require('../windows/tabs-firefox');
const { isPrivate } = require('../private-browsing');
const { isWindowPBSupported } = require('../private-browsing/utils')
const { isPrivateBrowsingSupported } = require('sdk/self');
const supportPrivateTabs = isPrivateBrowsingSupported && isWindowPBSupported;
Object.defineProperties(tabs, {
open: { value: function open(options) {
if (options.inNewWindow)
if (options.inNewWindow) {
// `tabs` option is under review and may be removed.
return browserWindows.open({ tabs: [ options ] });
// Open in active window if new window was not required.
return browserWindows.activeWindow.tabs.open(options);
windows.open({
tabs: [ options ],
isPrivate: options.isPrivate
});
return undefined;
}
// Open in active window if new window was not required..
let activeWindow = windows.activeWindow;
let privateState = !!options.isPrivate;
// if the active window is in the state that we need then use it
if (!supportPrivateTabs || privateState === isPrivate(activeWindow)) {
activeWindow.tabs.open(options);
}
else {
// find a window in the state that we need
let window = getWindow(privateState);
if (window) {
window.tabs.open(options);
}
// open a window in the state that we need
else {
windows.open({
tabs: [ options ],
isPrivate: options.isPrivate
});
}
}
return undefined;
}}
});
function getWindow(privateState) {
for each (let window in windows) {
if (privateState === isPrivate(window)) {
return window;
}
}
return null;
}
// Workaround for bug 674195. Freezing objects from other compartments fail,
// so we use `Object.freeze` from the same component as objects
// `hasOwnProperty`. Since `hasOwnProperty` here will be from other component

View File

@ -102,10 +102,13 @@ function openTab(window, url, options) {
return window.BrowserApp.addTab(url, {
selected: options.inBackground ? false : true,
pinned: options.isPinned || false,
isPrivate: options.private || false
isPrivate: options.isPrivate || false
});
}
return window.gBrowser.addTab(url);
let tab = window.gBrowser.addTab(url);
if (!options.inBackground)
activateTab(tab);
return tab;
};
exports.openTab = openTab;

View File

@ -19,7 +19,8 @@ const { Cc, Ci, Cr } = require('chrome'),
{ ns } = require('../core/namespace'),
{ observer: windowObserver } = require('./observer'),
{ getOwnerWindow } = require('../private-browsing/window/utils'),
viewNS = require('sdk/core/namespace').ns();
viewNS = require('../core/namespace').ns(),
{ isPrivateBrowsingSupported } = require('../self');
/**
* Window trait composes safe wrappers for browser window that are E10S
@ -68,7 +69,7 @@ const BrowserWindowTrait = Trait.compose(
this._tabOptions = [ Options(options.url) ];
}
this._private = !!options.private;
this._isPrivate = isPrivateBrowsingSupported && !!options.isPrivate;
this._load();
@ -209,9 +210,13 @@ const browserWindows = Trait.resolve({ toString: null }).compose(
return window ? BrowserWindow({window: window}) : null;
},
open: function open(options) {
if (typeof options === "string")
if (typeof options === "string") {
// `tabs` option is under review and may be removed.
options = { tabs: [Options(options)] };
options = {
tabs: [Options(options)],
isPrivate: isPrivateBrowsingSupported && options.isPrivate
};
}
return BrowserWindow(options);
},

View File

@ -41,7 +41,7 @@ const WindowLoader = Trait.compose({
_load: function _load() {
if (this.__window) return;
this._window = openDialog({
private: this._private,
private: this._isPrivate,
args: this._tabOptions.map(function(options) options.url).join("|")
});
},

View File

@ -17,11 +17,15 @@ const { EventTarget } = require('../event/target');
const { when: unload } = require('../system/unload');
const { windowIterator } = require('../deprecated/window-utils');
const { List, addListItem, removeListItem } = require('../util/list');
const { isPrivateBrowsingSupported } = require('sdk/self');
const { isTabPBSupported } = require('sdk/private-browsing/utils');
const mainWindow = windowNS(browserWindows.activeWindow).window;
const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec';
const supportPrivateTabs = isPrivateBrowsingSupported && isTabPBSupported;
const Tabs = Class({
implements: [ List ],
extends: EventTarget,
@ -53,7 +57,8 @@ const Tabs = Class({
}
let rawTab = openTab(windowNS(activeWin).window, options.url, {
inBackground: options.inBackground
inBackground: options.inBackground,
isPrivate: supportPrivateTabs && options.isPrivate
});
// by now the tab has been created

View File

@ -13,9 +13,10 @@ const { Tab } = require("../tabs/tab");
const { EventEmitter } = require("../deprecated/events");
const { EVENTS } = require("../tabs/events");
const { getOwnerWindow, getActiveTab, getTabs,
openTab, activateTab } = require("../tabs/utils");
openTab } = require("../tabs/utils");
const { Options } = require("../tabs/common");
const { observer: tabsObserver } = require("../tabs/observer");
const { isWindowPrivate } = require("../private-browsing/utils");
const TAB_BROWSER = "tabbrowser";
@ -152,11 +153,14 @@ const TabList = List.resolve({ constructor: "_init" }).compose(
_activeTab: null,
open: function open(options) {
let window = this._window;
let chromeWindow = window._window;
options = Options(options);
this._window._tabOptions.push(options);
let tab = openTab(this._window._window, options.url);
if (!options.inBackground)
activateTab(tab);
// save the tab options
window._tabOptions.push(options);
// open the tab
let tab = openTab(chromeWindow, options.url, options);
}
// This is ugly, but necessary. Will be removed by #596248
}).resolve({ toString: null })

View File

@ -161,6 +161,28 @@ parser_groups = (
default="firefox",
cmds=['test', 'run', 'testex', 'testpkgs',
'testall'])),
(("-o", "--overload-modules",), dict(dest="overload_modules",
help=("Overload JS modules integrated into"
" Firefox with the one from your SDK"
" repository"),
action="store_true",
default=False,
cmds=['run', 'test', 'testex', 'testpkgs',
'testall'])),
(("", "--strip-sdk",), dict(dest="bundle_sdk",
help=("Do not ship SDK modules in the xpi"),
action="store_false",
default=True,
cmds=['run', 'test', 'testex', 'testpkgs',
'testall', 'xpi'])),
(("", "--force-use-bundled-sdk",), dict(dest="force_use_bundled_sdk",
help=("When --strip-sdk isn't passed, "
"force using sdk modules shipped in "
"the xpi instead of firefox ones"),
action="store_true",
default=False,
cmds=['run', 'test', 'testex', 'testpkgs',
'testall', 'xpi'])),
(("", "--no-run",), dict(dest="no_run",
help=("Instead of launching the "
"application, just show the command "
@ -764,6 +786,14 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
harness_options.update(build)
# When cfx is run from sdk root directory, we will strip sdk modules and
# override them with local modules.
# So that integration tools will continue to work and use local modules
if os.getcwd() == env_root:
options.bundle_sdk = True
options.force_use_bundled_sdk = False
options.overload_modules = True
extra_environment = {}
if command == "test":
# This should be contained in the test runner package.
@ -792,14 +822,32 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
mydir = os.path.dirname(os.path.abspath(__file__))
app_extension_dir = os.path.join(mydir, "../../app-extension")
if target_cfg.get('preferences'):
harness_options['preferences'] = target_cfg.get('preferences')
harness_options['manifest'] = manifest.get_harness_options_manifest()
harness_options['allTestModules'] = manifest.get_all_test_modules()
if len(harness_options['allTestModules']) == 0 and command == "test":
sys.exit(0)
harness_options['manifest'] = \
manifest.get_harness_options_manifest(options.bundle_sdk)
# Gives an hint to tell if sdk modules are bundled or not
harness_options['is-sdk-bundled'] = options.bundle_sdk
if options.force_use_bundled_sdk:
if not options.bundle_sdk:
print >>sys.stderr, ("--force-use-bundled-sdk and --strip-sdk "
"can't be used at the same time.")
sys.exit(1)
if options.overload_modules:
print >>sys.stderr, ("--force-use-bundled-sdk and --overload-modules "
"can't be used at the same time.")
sys.exit(1)
# Pass a flag in order to force using sdk modules shipped in the xpi
harness_options['force-use-bundled-sdk'] = True
# Pass the list of absolute path for all test modules
if command == "test":
harness_options['allTestModules'] = manifest.get_all_test_modules()
if len(harness_options['allTestModules']) == 0:
sys.exit(0)
from cuddlefish.rdf import gen_manifest, RDFUpdate
@ -825,7 +873,7 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
# build_manifest earlier
used_files = None
if command == "xpi":
used_files = set(manifest.get_used_files())
used_files = set(manifest.get_used_files(options.bundle_sdk))
if options.no_strip_xpi:
used_files = None # disables the filter, includes all files
@ -872,7 +920,11 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
norun=options.no_run,
used_files=used_files,
enable_mobile=options.enable_mobile,
mobile_app_name=options.mobile_app_name)
mobile_app_name=options.mobile_app_name,
env_root=env_root,
is_running_tests=(command == "test"),
overload_modules=options.overload_modules,
bundle_sdk=options.bundle_sdk)
except ValueError, e:
print ""
print "A given cfx option has an inappropriate value:"

View File

@ -260,7 +260,7 @@ class ManifestBuilder:
used.add(package)
return sorted(used)
def get_used_files(self):
def get_used_files(self, bundle_sdk_modules):
# returns all .js files that we reference, plus data/ files. You will
# need to add the loader, off-manifest files that it needs, and
# generated metadata.
@ -269,16 +269,22 @@ class ManifestBuilder:
yield absname
for me in self.get_module_entries():
yield me.js_filename
# Do not add manifest entries for system modules,
# so that we won't ship SDK files.
if me.packageName != "addon-sdk" or bundle_sdk_modules:
yield me.js_filename
def get_all_test_modules(self):
return self.test_modules
def get_harness_options_manifest(self):
def get_harness_options_manifest(self, bundle_sdk_modules):
manifest = {}
for me in self.get_module_entries():
path = me.get_path()
manifest[path] = me.get_entry_for_manifest()
# Do not add manifest entries for system modules,
# so that we won't ship SDK files.
if me.packageName != "addon-sdk" or bundle_sdk_modules:
manifest[path] = me.get_entry_for_manifest()
return manifest
def get_manifest_entry(self, package, section, module):

View File

@ -380,7 +380,11 @@ def run_app(harness_root_dir, manifest_rdf, harness_options,
logfile=None, addons=None, args=None, extra_environment={},
norun=None,
used_files=None, enable_mobile=False,
mobile_app_name=None):
mobile_app_name=None,
env_root=None,
is_running_tests=False,
overload_modules=False,
bundle_sdk=True):
if binary:
binary = os.path.expanduser(binary)
@ -392,6 +396,22 @@ def run_app(harness_root_dir, manifest_rdf, harness_options,
cmdargs = []
preferences = dict(DEFAULT_COMMON_PREFS)
# Overload global commonjs path with lib/ folders
file_scheme = "file://"
# win32 file scheme needs 3 slashes
if not env_root.startswith("/"):
file_scheme = file_scheme + "/"
addon_id = harness_options["jetpackID"]
pref_prefix = "extensions.modules." + addon_id + ".path"
if overload_modules:
preferences[pref_prefix] = file_scheme + \
os.path.join(env_root, "lib").replace("\\", "/") + "/"
# Overload tests/ mapping with test/ folder, only when running test
if is_running_tests:
preferences[pref_prefix + ".tests"] = file_scheme + \
os.path.join(env_root, "test").replace("\\", "/") + "/"
# For now, only allow running on Mobile with --force-mobile argument
if app_type in ["fennec", "fennec-on-device"] and not enable_mobile:
print """
@ -483,7 +503,8 @@ def run_app(harness_root_dir, manifest_rdf, harness_options,
manifest=manifest_rdf,
xpi_path=xpi_path,
harness_options=harness_options,
limit_to=used_files)
limit_to=used_files,
bundle_sdk=bundle_sdk)
addons.append(xpi_path)
starttime = last_output_time = time.time()

View File

@ -43,7 +43,7 @@ class Basic(unittest.TestCase):
# target_cfg.dependencies is not provided, so we'll search through
# all known packages (everything in 'deps').
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False)
m = m.get_harness_options_manifest()
m = m.get_harness_options_manifest(False)
def assertReqIs(modname, reqname, path):
reqs = m["one/%s" % modname]["requirements"]
@ -72,7 +72,7 @@ class Basic(unittest.TestCase):
[target_cfg.name, "addon-sdk"])
self.failUnlessEqual(deps, ["addon-sdk", "three"])
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False)
m = m.get_harness_options_manifest()
m = m.get_harness_options_manifest(False)
def assertReqIs(modname, reqname, path):
reqs = m["three/%s" % modname]["requirements"]
self.failUnlessEqual(reqs[reqname], path)
@ -90,7 +90,7 @@ class Basic(unittest.TestCase):
self.failUnlessEqual(deps, ["addon-sdk", "five"])
# all we care about is that this next call doesn't raise an exception
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False)
m = m.get_harness_options_manifest()
m = m.get_harness_options_manifest(False)
reqs = m["five/main"]["requirements"]
self.failUnlessEqual(reqs, {});

View File

@ -202,7 +202,7 @@ class SmallXPI(unittest.TestCase):
[target_cfg.name, "addon-sdk"])
addon_sdk_dir = pkg_cfg.packages["addon-sdk"].lib[0]
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False)
used_files = list(m.get_used_files())
used_files = list(m.get_used_files(True))
here = up(os.path.abspath(__file__))
def absify(*parts):
fn = os.path.join(here, "linker-files", *parts)

View File

@ -22,7 +22,8 @@ def mkzipdir(zf, path):
zf.writestr(dirinfo, "")
def build_xpi(template_root_dir, manifest, xpi_path,
harness_options, limit_to=None, extra_harness_options={}):
harness_options, limit_to=None, extra_harness_options={},
bundle_sdk=True):
zf = zipfile.ZipFile(xpi_path, "w", zipfile.ZIP_DEFLATED)
open('.install.rdf', 'w').write(str(manifest))
@ -84,6 +85,10 @@ def build_xpi(template_root_dir, manifest, xpi_path,
# of all packages sections directories
for packageName in harness_options['packages']:
base_arcpath = ZIPSEP.join(['resources', packageName])
# Eventually strip sdk files. We need to do that in addition to the
# whilelist as the whitelist is only used for `cfx xpi`:
if not bundle_sdk and packageName == 'addon-sdk':
continue
# Always write the top directory, even if it contains no files, since
# the harness will try to access it.
dirs_to_create.add(base_arcpath)

View File

@ -3,11 +3,164 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
const { Ci } = require('chrome');
const { isPrivateBrowsingSupported } = require('sdk/self');
const tabs = require('sdk/tabs');
const { browserWindows: windows } = require('sdk/windows');
const { isPrivate } = require('sdk/private-browsing');
const { getOwnerWindow } = require('sdk/private-browsing/window/utils');
const { is } = require('sdk/system/xul-app');
const { isWindowPBSupported, isTabPBSupported } = require('sdk/private-browsing/utils');
const TAB_URL = 'data:text/html;charset=utf-8,TEST-TAB';
exports.testIsPrivateBrowsingTrue = function(assert) {
assert.ok(isPrivateBrowsingSupported,
'isPrivateBrowsingSupported property is true');
};
// test tab.open with isPrivate: true
// test isPrivate on a tab
// test getOwnerWindow on windows and tabs
exports.testGetOwnerWindow = function(assert, done) {
let window = windows.activeWindow;
let chromeWindow = getOwnerWindow(window);
assert.ok(chromeWindow instanceof Ci.nsIDOMWindow, 'associated window is found');
tabs.open({
url: 'about:blank',
isPrivate: true,
onOpen: function(tab) {
// test that getOwnerWindow works as expected
if (is('Fennec')) {
assert.notStrictEqual(chromeWindow, getOwnerWindow(tab));
assert.ok(getOwnerWindow(tab) instanceof Ci.nsIDOMWindow);
}
else {
if (isWindowPBSupported) {
assert.notStrictEqual(chromeWindow,
getOwnerWindow(tab),
'associated window is not the same for window and window\'s tab');
}
else {
assert.strictEqual(chromeWindow,
getOwnerWindow(tab),
'associated window is the same for window and window\'s tab');
}
}
let pbSupported = isTabPBSupported || isWindowPBSupported;
// test that the tab is private if it should be
assert.equal(isPrivate(tab), pbSupported);
assert.equal(isPrivate(getOwnerWindow(tab)), pbSupported);
tab.close(function() done());
}
});
};
// test that it is possible to open a private tab
exports.testTabOpenPrivate = function(assert, done) {
tabs.open({
url: TAB_URL,
isPrivate: true,
onReady: function(tab) {
assert.equal(tab.url, TAB_URL, 'opened correct tab');
assert.equal(isPrivate(tab), (isWindowPBSupported || isTabPBSupported));
tab.close(function() {
done();
});
}
});
}
// test that it is possible to open a non private tab
exports.testTabOpenPrivateDefault = function(assert, done) {
tabs.open({
url: TAB_URL,
onReady: function(tab) {
assert.equal(tab.url, TAB_URL, 'opened correct tab');
assert.equal(isPrivate(tab), false);
tab.close(function() {
done();
});
}
});
}
// test that it is possible to open a non private tab in explicit case
exports.testTabOpenPrivateOffExplicit = function(assert, done) {
tabs.open({
url: TAB_URL,
isPrivate: false,
onReady: function(tab) {
assert.equal(tab.url, TAB_URL, 'opened correct tab');
assert.equal(isPrivate(tab), false);
tab.close(function() {
done();
});
}
});
}
// test windows.open with isPrivate: true
// test isPrivate on a window
if (!is('Fennec')) {
// test that it is possible to open a private window
exports.testWindowOpenPrivate = function(assert, done) {
windows.open({
url: TAB_URL,
isPrivate: true,
onOpen: function(window) {
let tab = window.tabs[0];
tab.once('ready', function() {
assert.equal(tab.url, TAB_URL, 'opened correct tab');
assert.equal(isPrivate(tab), isWindowPBSupported, 'tab is private');
window.close(function() {
done();
});
});
}
});
};
exports.testIsPrivateOnWindowOn = function(assert, done) {
windows.open({
isPrivate: true,
onOpen: function(window) {
assert.equal(isPrivate(window), isWindowPBSupported, 'isPrivate for a window is true when it should be');
assert.equal(isPrivate(window.tabs[0]), isWindowPBSupported, 'isPrivate for a tab is false when it should be');
window.close(done);
}
});
};
exports.testIsPrivateOnWindowOffImplicit = function(assert, done) {
windows.open({
onOpen: function(window) {
assert.equal(isPrivate(window), false, 'isPrivate for a window is false when it should be');
assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be');
window.close(done);
}
})
}
exports.testIsPrivateOnWindowOffExplicit = function(assert, done) {
windows.open({
isPrivate: false,
onOpen: function(window) {
assert.equal(isPrivate(window), false, 'isPrivate for a window is false when it should be');
assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be');
window.close(done);
}
})
}
}
require('sdk/test/runner').runTestsFromModule(module);

View File

@ -12,7 +12,7 @@ exports.testIsPrivateOnTab = function(test) {
test.assert(!pb.isPrivate(chromeWindow), 'the top level window is not private');
let rawTab = openTab(chromeWindow, 'data:text/html,<h1>Hi!</h1>', {
private: true
isPrivate: true
});
// test that the tab is private

View File

@ -32,10 +32,10 @@ exports.testPerWindowPrivateBrowsingGetter = function(assert, done) {
exports.testIsPrivateOnWindowOn = function(assert, done) {
windows.open({
private: true,
isPrivate: true,
onOpen: function(window) {
assert.equal(isPrivate(window), true, 'isPrivate for a window is true when it should be');
assert.equal(isPrivate(window.tabs[0]), true, 'isPrivate for a tab is false when it should be');
assert.equal(isPrivate(window), false, 'isPrivate for a window is true when it should be');
assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be');
window.close(done);
}
});

View File

@ -93,7 +93,7 @@ exports.testDeprecateEvent = function(assert, done) {
emit(testObj, 'water');
});
assert.equal(errors.length, 1, "only one error is dispatched");
let msg = errors[0];console.log(msg);
let msg = errors[0];
assert.ok(msg.indexOf("BAD") !== -1, "message contains the given message");
assert.ok(msg.indexOf("deprecateEvent") !== -1,
"message contains name of the caller function");

View File

@ -7,6 +7,7 @@ const { Ci } = require('chrome');
const { pb, pbUtils, getOwnerWindow } = require('./private-browsing/helper');
const { merge } = require('sdk/util/object');
const windows = require('sdk/windows').browserWindows;
const tabs = require('sdk/tabs');
const winUtils = require('sdk/window/utils');
const { isPrivateBrowsingSupported } = require('sdk/self');
const { is } = require('sdk/system/xul-app');
@ -70,9 +71,9 @@ exports.testGetOwnerWindow = function(test) {
let chromeWindow = getOwnerWindow(window);
test.assert(chromeWindow instanceof Ci.nsIDOMWindow, 'associated window is found');
window.tabs.open({
tabs.open({
url: 'about:blank',
private: true, // should be ignored in this case
isPrivate: true,
onOpen: function(tab) {
// test that getOwnerWindow works as expected
if (is('Fennec')) {
@ -86,6 +87,7 @@ exports.testGetOwnerWindow = function(test) {
// test that the tab is not private
// private flag should be ignored by default
test.assert(!isPrivate(tab));
test.assert(!isPrivate(getOwnerWindow(tab)));
tab.close(function() test.done());
}

View File

@ -6,6 +6,8 @@
const { Loader } = require('sdk/test/loader');
const { browserWindows } = require('sdk/windows');
const tabs = require('sdk/tabs');
const { isPrivate } = require('sdk/private-browsing');
const { isWindowPBSupported, isTabPBSupported } = require('sdk/private-browsing/utils');
const URL = 'data:text/html;charset=utf-8,<html><head><title>#title#</title></head></html>';
@ -289,8 +291,29 @@ exports.testTabContentTypeAndReload = function(test) {
}
else {
test.assertEqual(tab.contentType, "text/xml");
tab.close(function() test.done());
tab.close(function() {
test.done();
});
}
}
});
};
// test that it is possible to open a private tab
exports.testTabOpenPrivate = function(test) {
test.waitUntilDone();
let url = 'about:blank';
tabs.open({
url: url,
isPrivate: true,
onReady: function(tab) {
test.assertEqual(tab.url, url, 'opened correct tab');
test.assertEqual(isPrivate(tab), false, 'private tabs arenot supported by default');
tab.close(function() {
test.done();
});
}
});
}

View File

@ -12,6 +12,8 @@ const wm = Cc['@mozilla.org/appshell/window-mediator;1'].
const { browserWindows } = require("sdk/windows");
const tabs = require("sdk/tabs");
const { WindowTracker } = require("sdk/deprecated/window-utils");
const { isPrivate } = require('sdk/private-browsing');
const { isWindowPBSupported } = require('sdk/private-browsing/utils');
// TEST: open & close window
exports.testOpenAndCloseWindow = function(test) {
@ -101,7 +103,7 @@ exports.testWindowTabsObject = function(test) {
}
browserWindows.open({
url: "data:text/html;charset=utf-8,<title>tab 1</title>",
onActivate: function onOpen(win) {
onActivate: function onActivate(win) {
window = win;
runTest();
},
@ -370,3 +372,24 @@ exports.testTrackWindows = function(test) {
openWindow();
}
// test that it is not possible to open a private window by default
exports.testWindowOpenPrivateDefault = function(test) {
test.waitUntilDone();
browserWindows.open({
url: 'about:mozilla',
isPrivate: true,
onOpen: function(window) {
let tab = window.tabs[0];
tab.once('ready', function() {
test.assertEqual(tab.url, 'about:mozilla', 'opened correct tab');
test.assertEqual(isPrivate(tab), false, 'tab is not private');
window.close(function() {
test.done();
});
});
}
});
}

View File

@ -86,48 +86,75 @@ WebappsActor.prototype = {
});
},
installHostedApp: function wa_actorInstallHosted(aDir, aId, aType) {
_getAppType: function wa_actorGetAppType(aType) {
let type = Ci.nsIPrincipal.APP_STATUS_INSTALLED;
if (aType) {
type = aType == "privileged" ? Ci.nsIPrincipal.APP_STATUS_PRIVILEGED
: aType == "certified" ? Ci.nsIPrincipal.APP_STATUS_CERTIFIED
: Ci.nsIPrincipal.APP_STATUS_INSTALLED;
}
return type;
},
installHostedApp: function wa_actorInstallHosted(aDir, aId) {
debug("installHostedApp");
let self = this;
let runnable = {
run: function run() {
try {
// The destination directory for this app.
let installDir = FileUtils.getDir(DIRECTORY_NAME,
["webapps", aId], true);
// Move manifest.webapp to the destination directory.
let manFile = aDir.clone();
manFile.append("manifest.webapp");
manFile.moveTo(installDir, "manifest.webapp");
// Read the origin and manifest url from metadata.json
let metaFile = aDir.clone();
metaFile.append("metadata.json");
DOMApplicationRegistry._loadJSONAsync(metaFile, function(aMetadata) {
if (!aMetadata) {
self._sendError("Error Parsing metadata.json", aId);
DOMApplicationRegistry._loadJSONAsync(manFile, function(aManifest) {
if (!aManifest) {
self._sendError("Error Parsing manifest.webapp", aId);
return;
}
if (!aMetadata.origin) {
self._sendError("Missing 'origin' propery in metadata.json", aId);
let appType = self._getAppType(aManifest.type);
// In production builds, don't allow installation of certified apps.
#ifdef MOZ_OFFICIAL
if (appType == Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
self._sendError("Installing certified apps is not allowed.", aId);
return;
}
#endif
// The destination directory for this app.
let installDir = FileUtils.getDir(DIRECTORY_NAME,
["webapps", aId], true);
manFile.moveTo(installDir, "manifest.webapp");
let origin = aMetadata.origin;
let manifestURL = aMetadata.manifestURL ||
origin + "/manifest.webapp";
// Create a fake app object with the minimum set of properties we need.
let app = {
origin: origin,
installOrigin: aMetadata.installOrigin || origin,
manifestURL: manifestURL,
appStatus: aType
}
// Read the origin and manifest url from metadata.json
let metaFile = aDir.clone();
metaFile.append("metadata.json");
DOMApplicationRegistry._loadJSONAsync(metaFile, function(aMetadata) {
if (!aMetadata) {
self._sendError("Error Parsing metadata.json", aId);
return;
}
self._registerApp(app, aId, aDir);
if (!aMetadata.origin) {
self._sendError("Missing 'origin' property in metadata.json", aId);
return;
}
let origin = aMetadata.origin;
let manifestURL = aMetadata.manifestURL ||
origin + "/manifest.webapp";
// Create a fake app object with the minimum set of properties we need.
let app = {
origin: origin,
installOrigin: aMetadata.installOrigin || origin,
manifestURL: manifestURL,
appStatus: appType
};
self._registerApp(app, aId, aDir);
});
});
} catch(e) {
// If anything goes wrong, just send it back.
@ -140,7 +167,7 @@ WebappsActor.prototype = {
Ci.nsIThread.DISPATCH_NORMAL);
},
installPackagedApp: function wa_actorInstallPackaged(aDir, aId, aType) {
installPackagedApp: function wa_actorInstallPackaged(aDir, aId) {
debug("installPackagedApp");
let self = this;
@ -151,34 +178,45 @@ WebappsActor.prototype = {
let installDir = FileUtils.getDir(DIRECTORY_NAME,
["webapps", aId], true);
// Move application.zip to the destination directory.
// Move application.zip to the destination directory, and
// extract manifest.webapp there.
let zipFile = aDir.clone();
zipFile.append("application.zip");
zipFile.moveTo(installDir, "application.zip");
// Extract the manifest.webapp file from the zip.
zipFile = installDir.clone();
zipFile.append("application.zip");
let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"]
.createInstance(Ci.nsIZipReader);
zipReader.open(zipFile);
let manFile = installDir.clone();
manFile.append("manifest.webapp");
zipReader.extract("manifest.webapp", manFile);
zipReader.close();
zipFile.moveTo(installDir, "application.zip");
let origin = "app://" + aId;
DOMApplicationRegistry._loadJSONAsync(manFile, function(aManifest) {
if (!aManifest) {
self._sendError("Error Parsing manifest.webapp", aId);
}
// Create a fake app object with the minimum set of properties we need.
let app = {
origin: origin,
installOrigin: origin,
manifestURL: origin + "/manifest.webapp",
appStatus: aType
}
let appType = self._getAppType(aManifest.type);
self._registerApp(app, aId, aDir);
// In production builds, don't allow installation of certified apps.
#ifdef MOZ_OFFICIAL
if (appType == Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
self._sendError("Installing certified apps is not allowed.", aId);
return;
}
#endif
let origin = "app://" + aId;
// Create a fake app object with the minimum set of properties we need.
let app = {
origin: origin,
installOrigin: origin,
manifestURL: origin + "/manifest.webapp",
appStatus: appType
}
self._registerApp(app, aId, aDir);
});
} catch(e) {
// If anything goes wrong, just send it back.
self._sendError(e.toString(), aId);
@ -195,9 +233,6 @@ WebappsActor.prototype = {
* the files for the app in $TMP/b2g/$appId :
* For packaged apps: application.zip
* For hosted apps: metadata.json and manifest.webapp
* @param appType : The privilege status of the app, as defined in
* nsIPrincipal. It's optional and default to
* APP_STATUS_INSTALLED
*/
install: function wa_actorInstall(aRequest) {
debug("install");
@ -212,8 +247,6 @@ WebappsActor.prototype = {
message: "missing parameter appId" }
}
let appType = aRequest.appType || Ci.nsIPrincipal.APP_STATUS_INSTALLED;
// Check that we are not overriding a preinstalled application.
let reg = DOMApplicationRegistry;
if (appId in reg.webapps && reg.webapps[appId].removable === false) {
@ -222,15 +255,6 @@ WebappsActor.prototype = {
}
}
// In production builds, don't allow installation of certified apps.
#ifdef MOZ_OFFICIAL
if (appType == Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
return { error: "badParameterType",
message: "Installing certified apps is not allowed."
}
}
#endif
let appDir = FileUtils.getDir("TmpD", ["b2g", appId], false, false);
if (!appDir || !appDir.exists()) {
@ -243,7 +267,7 @@ WebappsActor.prototype = {
testFile.append("application.zip");
if (testFile.exists()) {
this.installPackagedApp(appDir, appId, appType);
this.installPackagedApp(appDir, appId);
} else {
let missing =
["manifest.webapp", "metadata.json"]
@ -261,7 +285,7 @@ WebappsActor.prototype = {
message: "hosted app file is missing" }
}
this.installHostedApp(appDir, appId, appType);
this.installHostedApp(appDir, appId);
}
return { appId: appId, path: appDir.path }

View File

@ -177,15 +177,6 @@ UpdatePrompt.prototype = {
showUpdateError: function UP_showUpdateError(aUpdate) {
log("Update error, state: " + aUpdate.state + ", errorCode: " +
aUpdate.errorCode);
if (aUpdate.state == "applied" && aUpdate.errorCode == 0) {
// The user chose to apply the update later and then tried to download
// it again. If there isn't a new update to download, then the updater
// code will detect that there is an update waiting to be installed and
// fail. So reprompt the user to apply the update.
this.showApplyPrompt(aUpdate);
return;
}
this.sendUpdateEvent("update-error", aUpdate);
this.setUpdateStatus(aUpdate.statusText);
},
@ -314,6 +305,14 @@ UpdatePrompt.prototype = {
return;
}
// If the update has already been downloaded and applied, then
// Services.aus.downloadUpdate will return immediately and not
// call showUpdateDownloaded, so we detect this.
if (aUpdate.state == "applied" && aUpdate.errorCode == 0) {
this.showUpdateDownloaded(aUpdate, true);
return;
}
log("Error downloading update " + aUpdate.name + ": " + aUpdate.errorCode);
if (aUpdate.errorCode == FILE_ERROR_TOO_BIG) {
aUpdate.statusText = "file-too-big";
@ -412,7 +411,13 @@ UpdatePrompt.prototype = {
break;
case "update-available-result":
this.handleAvailableResult(detail);
this._update = null;
// If we started the apply prompt timer, this means that we're waiting
// for the user to press Later or Install Now. In this situation we
// don't want to clear this._update, becuase handleApplyPromptResult
// needs it.
if (this._applyPromptTimer == null) {
this._update = null;
}
break;
case "update-download-cancel":
this.handleDownloadCancel();
@ -503,6 +508,7 @@ UpdatePrompt.prototype = {
log("Timed out waiting for result, restarting");
this._applyPromptTimer = null;
this.finishUpdate();
this._update = null;
}
},

View File

@ -2,7 +2,7 @@
"config_version": 1,
"tooltool_manifest": "releng-otoro.tt",
"mock_target": "mozilla-centos6-i386",
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel"],
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "java-1.6.0-openjdk-devel"],
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
"build_targets": [],
"upload_files": [

View File

@ -2,7 +2,7 @@
"config_version": 1,
"tooltool_manifest": "releng-unagi.tt",
"mock_target": "mozilla-centos6-i386",
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel"],
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "java-1.6.0-openjdk-devel"],
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
"build_targets": [],
"upload_files": [

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1360959670000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1361213668000">
<emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*">
@ -211,6 +211,8 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
</emItem>
<emItem blockID="i258" id="helperbar@helperbar.com">
<versionRange minVersion="0" maxVersion="1.0" severity="1">
</versionRange>
@ -282,8 +284,10 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
</emItem>
<emItem blockID="i286" id="{58bd07eb-0ee0-4df0-8121-dc9b693373df}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
<versionRange minVersion="2.1" maxVersion="3.3">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">

View File

@ -7,6 +7,7 @@ let Ci = Components.interfaces;
let Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource:///modules/RecentWindow.jsm");
const nsIWebNavigation = Ci.nsIWebNavigation;
@ -4864,9 +4865,8 @@ nsBrowserAccess.prototype = {
if (window.toolbar.visible)
win = window;
else {
win = Cc["@mozilla.org/browser/browserglue;1"]
.getService(Ci.nsIBrowserGlue)
.getMostRecentBrowserWindow();
let isPrivate = PrivateBrowsingUtils.isWindowPrivate(aOpener || window);
win = RecentWindow.getMostRecentBrowserWindow({private: isPrivate});
needToFocusWin = true;
}
@ -7102,25 +7102,27 @@ var gIdentityHandler = {
this._identityPopup.hidePopup();
},
_popupOpenTime : null,
/**
* Click handler for the identity-box element in primary chrome.
*/
handleIdentityButtonEvent : function(event) {
this._popupOpenTime = new Date();
TelemetryStopwatch.start("FX_IDENTITY_POPUP_OPEN_MS");
event.stopPropagation();
if ((event.type == "click" && event.button != 0) ||
(event.type == "keypress" && event.charCode != KeyEvent.DOM_VK_SPACE &&
event.keyCode != KeyEvent.DOM_VK_RETURN))
event.keyCode != KeyEvent.DOM_VK_RETURN)) {
TelemetryStopwatch.cancel("FX_IDENTITY_POPUP_OPEN_MS");
return; // Left click, space or enter only
}
// Don't allow left click, space or enter if the location
// is chrome UI or the location has been modified.
if (this._mode == this.IDENTITY_MODE_CHROMEUI ||
gURLBar.getAttribute("pageproxystate") != "valid")
gURLBar.getAttribute("pageproxystate") != "valid") {
TelemetryStopwatch.cancel("FX_IDENTITY_POPUP_OPEN_MS");
return;
}
// Make sure that the display:none style we set in xul is removed now that
// the popup is actually needed
@ -7142,13 +7144,7 @@ var gIdentityHandler = {
},
onPopupShown : function(event) {
let openingDuration = new Date() - this._popupOpenTime;
this._popupOpenTime = null;
try {
Services.telemetry.getHistogramById("FX_IDENTITY_POPUP_OPEN_MS").add(openingDuration);
} catch (ex) {
Components.utils.reportError("Unable to report telemetry for FX_IDENTITY_POPUP_OPEN_MS.");
}
TelemetryStopwatch.finish("FX_IDENTITY_POPUP_OPEN_MS");
document.getElementById('identity-popup-more-info-button').focus();
},

View File

@ -1175,32 +1175,32 @@
#ifndef XP_UNIX
<svg:svg height="0">
<svg:clipPath id="winstripe-keyhole-forward-clip-path" clipPathUnits="objectBoundingBox">
<svg:clipPath id="windows-keyhole-forward-clip-path" clipPathUnits="objectBoundingBox">
<svg:path d="M 0,0 C 0.16,0.11 0.28,0.29 0.28,0.5 0.28,0.71 0.16,0.89 0,1 L 1,1 1,0 0,0 z"/>
</svg:clipPath>
<svg:clipPath id="winstripe-urlbar-back-button-clip-path" clipPathUnits="userSpaceOnUse">
<svg:clipPath id="windows-urlbar-back-button-clip-path" clipPathUnits="userSpaceOnUse">
<svg:path d="M 0,0 0,7.8 C 2.5,11 4,14 4,18 4,22 2.5,25 0,28 l 0,22 10000,0 0,-50 L 0,0 z"/>
</svg:clipPath>
</svg:svg>
#endif
#ifdef XP_MACOSX
<svg:svg height="0">
<svg:clipPath id="pinstripe-keyhole-forward-clip-path" clipPathUnits="objectBoundingBox">
<svg:clipPath id="osx-keyhole-forward-clip-path" clipPathUnits="objectBoundingBox">
<svg:path d="M 0,0 C 0.15,0.12 0.25,0.3 0.25,0.5 0.25,0.7 0.15,0.88 0,1 L 1,1 1,0 0,0 z"/>
</svg:clipPath>
<svg:clipPath id="pinstripe-urlbar-back-button-clip-path" clipPathUnits="userSpaceOnUse">
<svg:clipPath id="osx-urlbar-back-button-clip-path" clipPathUnits="userSpaceOnUse">
<svg:path d="m 0,-5 0,4.03 C 3.6,1.8 6,6.1 6,11 6,16 3.6,20 0,23 l 0,27 10000,0 0,-55 L 0,-5 z"/>
</svg:clipPath>
<svg:clipPath id="pinstripe-tab-ontop-left-curve-clip-path" clipPathUnits="userSpaceOnUse">
<svg:clipPath id="osx-tab-ontop-left-curve-clip-path" clipPathUnits="userSpaceOnUse">
<svg:path d="M 9,0 C 7.3,0 6,1.3 6,3 l 0,14 c 0,3 -2.2,5 -5,5 l -1,0 0,1 12,0 0,-1 0,-19 0,-3 -3,0 z"/>
</svg:clipPath>
<svg:clipPath id="pinstripe-tab-ontop-right-curve-clip-path" clipPathUnits="userSpaceOnUse">
<svg:clipPath id="osx-tab-ontop-right-curve-clip-path" clipPathUnits="userSpaceOnUse">
<svg:path d="m 0,0 0,3 0,19 0,1 12,0 0,-1 -1,0 C 8.2,22 6,20 6,17 L 6,3 C 6,1.3 4.7,0 3,0 L 0,0 z"/>
</svg:clipPath>
<svg:clipPath id="pinstripe-tab-onbottom-left-curve-clip-path" clipPathUnits="userSpaceOnUse">
<svg:clipPath id="osx-tab-onbottom-left-curve-clip-path" clipPathUnits="userSpaceOnUse">
<svg:path d="m 0,0 0,1 1,0 c 2.8,0 5,2.2 5,5 l 0,14 c 0,2 1.3,3 3,3 l 3,0 0,-3 L 12,1 12,0 0,0 z"/>
</svg:clipPath>
<svg:clipPath id="pinstripe-tab-onbottom-right-curve-clip-path" clipPathUnits="userSpaceOnUse">
<svg:clipPath id="osx-tab-onbottom-right-curve-clip-path" clipPathUnits="userSpaceOnUse">
<svg:path d="m 0,0 0,1 0,19 0,3 3,0 c 1.7,0 3,-1 3,-3 L 6,6 C 6,3.2 8.2,1 11,1 L 12,1 12,0 0,0 z"/>
</svg:clipPath>
</svg:svg>

View File

@ -1897,6 +1897,7 @@
// That's gBrowser for the other window, not the tab's browser!
var remoteBrowser = aOtherTab.ownerDocument.defaultView.gBrowser;
var isPending = aOtherTab.hasAttribute("pending");
// First, start teardown of the other browser. Make sure to not
// fire the beforeunload event in the process. Close the other
@ -1904,21 +1905,34 @@
if (!remoteBrowser._beginRemoveTab(aOtherTab, true, true))
return;
// Workarounds for bug 458697
// Icon might have been set on DOMLinkAdded, don't override that.
let ourBrowser = this.getBrowserForTab(aOurTab);
let otherBrowser = aOtherTab.linkedBrowser;
if (!ourBrowser.mIconURL && otherBrowser.mIconURL)
this.setIcon(aOurTab, otherBrowser.mIconURL);
var isBusy = aOtherTab.hasAttribute("busy");
if (isBusy) {
aOurTab.setAttribute("busy", "true");
this._tabAttrModified(aOurTab);
if (aOurTab.selected)
this.mIsBusy = true;
}
this._swapBrowserDocShells(aOurTab, otherBrowser);
// If the other tab is pending (i.e. has not been restored, yet)
// then do not switch docShells but retrieve the other tab's state
// and apply it to our tab.
if (isPending) {
let ss = Cc["@mozilla.org/browser/sessionstore;1"]
.getService(Ci.nsISessionStore)
ss.setTabState(aOurTab, ss.getTabState(aOtherTab));
// Make sure to unregister any open URIs.
this._swapRegisteredOpenURIs(ourBrowser, otherBrowser);
} else {
// Workarounds for bug 458697
// Icon might have been set on DOMLinkAdded, don't override that.
if (!ourBrowser.mIconURL && otherBrowser.mIconURL)
this.setIcon(aOurTab, otherBrowser.mIconURL);
var isBusy = aOtherTab.hasAttribute("busy");
if (isBusy) {
aOurTab.setAttribute("busy", "true");
this._tabAttrModified(aOurTab);
if (aOurTab.selected)
this.mIsBusy = true;
}
this._swapBrowserDocShells(aOurTab, otherBrowser);
}
// Finish tearing down the tab that's going away.
remoteBrowser._endRemoveTab(aOtherTab);
@ -1949,15 +1963,8 @@
ourBrowser.webProgress.removeProgressListener(filter);
filter.removeProgressListener(tabListener);
// Restore current registered open URI.
if (ourBrowser.registeredOpenURI) {
this._placesAutocomplete.unregisterOpenPage(ourBrowser.registeredOpenURI);
delete ourBrowser.registeredOpenURI;
}
if (aOtherBrowser.registeredOpenURI) {
ourBrowser.registeredOpenURI = aOtherBrowser.registeredOpenURI;
delete aOtherBrowser.registeredOpenURI;
}
// Make sure to unregister any open URIs.
this._swapRegisteredOpenURIs(ourBrowser, aOtherBrowser);
// Swap the docshells
ourBrowser.swapDocShells(aOtherBrowser);
@ -1973,6 +1980,26 @@
</body>
</method>
<method name="_swapRegisteredOpenURIs">
<parameter name="aOurBrowser"/>
<parameter name="aOtherBrowser"/>
<body>
<![CDATA[
// If the current URI is registered as open remove it from the list.
if (aOurBrowser.registeredOpenURI) {
this._placesAutocomplete.unregisterOpenPage(aOurBrowser.registeredOpenURI);
delete aOurBrowser.registeredOpenURI;
}
// If the other/new URI is registered as open then copy it over.
if (aOtherBrowser.registeredOpenURI) {
aOurBrowser.registeredOpenURI = aOtherBrowser.registeredOpenURI;
delete aOtherBrowser.registeredOpenURI;
}
]]>
</body>
</method>
<method name="reloadAllTabs">
<body>
<![CDATA[

View File

@ -161,6 +161,7 @@ _BROWSER_FILES = \
browser_bug783614.js \
browser_bug797677.js \
browser_bug816527.js \
browser_bug817947.js \
browser_bug822367.js \
browser_bug832435.js \
browser_canonizeURL.js \

View File

@ -0,0 +1,56 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
const ss = Cc["@mozilla.org/browser/sessionstore;1"]
.getService(Ci.nsISessionStore);
const URL = "http://mochi.test:8888/browser/";
const PREF = "browser.sessionstore.restore_on_demand";
function test() {
waitForExplicitFinish();
Services.prefs.setBoolPref(PREF, true);
registerCleanupFunction(function () {
Services.prefs.clearUserPref(PREF);
});
preparePendingTab(function (aTab) {
let win = gBrowser.replaceTabWithWindow(aTab);
whenDelayedStartupFinished(win, function () {
let [tab] = win.gBrowser.tabs;
whenLoaded(tab.linkedBrowser, function () {
is(tab.linkedBrowser.currentURI.spec, URL, "correct url should be loaded");
ok(!tab.hasAttribute("pending"), "tab should not be pending");
win.close();
finish();
});
});
});
}
function preparePendingTab(aCallback) {
let tab = gBrowser.addTab(URL);
whenLoaded(tab.linkedBrowser, function () {
let state = ss.getTabState(tab);
gBrowser.removeTab(tab);
tab = gBrowser.addTab("about:blank");
whenLoaded(tab.linkedBrowser, function () {
ss.setTabState(tab, state);
ok(tab.hasAttribute("pending"), "tab should be pending");
aCallback(tab);
});
});
}
function whenLoaded(aElement, aCallback) {
aElement.addEventListener("load", function onLoad() {
aElement.removeEventListener("load", onLoad, true);
executeSoon(aCallback);
}, true);
}

View File

@ -222,14 +222,15 @@ function checkAutocompleteResults(aExpected, aCallback)
let uri = gController.getValueAt(i).replace(/^moz-action:[^,]+,/i, "");
info("Search for '" + uri + "' in open tabs.");
ok(uri in aExpected, "Registered open page found in autocomplete.");
let expected = uri in aExpected;
ok(expected, uri + " was found in autocomplete, was " + (expected ? "" : "not ") + "expected");
// Remove the found entry from expected results.
delete aExpected[uri];
}
// Make sure there is no reported open page that is not open.
for (let entry in aExpected) {
ok(false, "'" + entry + "' not found in autocomplete.");
ok(false, "'" + entry + "' should be found in autocomplete");
}
executeSoon(aCallback);

View File

@ -66,6 +66,7 @@ BRANDING_FILES := \
endif
BRANDING_DEST := $(DIST)/branding
BRANDING_TARGET := export
INSTALL_TARGETS += BRANDING
include $(topsrcdir)/config/rules.mk

View File

@ -66,6 +66,7 @@ BRANDING_FILES := \
endif
BRANDING_DEST := $(DIST)/branding
BRANDING_TARGET := export
INSTALL_TARGETS += BRANDING
include $(topsrcdir)/config/rules.mk

View File

@ -66,6 +66,7 @@ BRANDING_FILES := \
endif
BRANDING_DEST := $(DIST)/branding
BRANDING_TARGET := export
INSTALL_TARGETS += BRANDING
include $(topsrcdir)/config/rules.mk

View File

@ -66,6 +66,7 @@ BRANDING_FILES := \
endif
BRANDING_DEST := $(DIST)/branding
BRANDING_TARGET := export
INSTALL_TARGETS += BRANDING
include $(topsrcdir)/config/rules.mk

View File

@ -12,9 +12,6 @@ include $(DEPTH)/config/autoconf.mk
EXTRA_COMPONENTS = \
BrowserDownloads.manifest \
DownloadsUI.js \
$(NULL)
EXTRA_PP_COMPONENTS = \
DownloadsStartup.js \
$(NULL)

View File

@ -16,7 +16,7 @@ browser.jar:
content/browser/places/placesOverlay.xul (content/placesOverlay.xul)
* content/browser/places/menu.xml (content/menu.xml)
content/browser/places/tree.xml (content/tree.xml)
* content/browser/places/controller.js (content/controller.js)
content/browser/places/controller.js (content/controller.js)
content/browser/places/treeView.js (content/treeView.js)
* content/browser/places/browserPlacesViews.js (content/browserPlacesViews.js)
# keep the Places version of the history sidebar at history/history-panel.xul

View File

@ -15,7 +15,7 @@ EXTRA_COMPONENTS = \
PlacesProtocolHandler.js \
$(NULL)
EXTRA_PP_JS_MODULES = \
EXTRA_JS_MODULES = \
PlacesUIUtils.jsm \
$(NULL)

View File

@ -179,8 +179,8 @@ var gPrivacyPane = {
// select the remember forms history option
document.getElementById("browser.formfill.enable").value = true;
// select the accept cookies option
document.getElementById("network.cookie.cookieBehavior").value = 0;
// select the limit cookies option
document.getElementById("network.cookie.cookieBehavior").value = 3;
// select the cookie lifetime policy option
document.getElementById("network.cookie.lifetimePolicy").value = 0;
@ -363,9 +363,10 @@ var gPrivacyPane = {
* network.cookie.cookieBehavior
* - determines how the browser should handle cookies:
* 0 means enable all cookies
* 1 means reject third party cookies; see
* netwerk/cookie/src/nsCookieService.cpp for a hairier definition
* 1 means reject all third party cookies
* 2 means disable all cookies
* 3 means reject third party cookies unless at least one is already set for the eTLD
* see netwerk/cookie/src/nsCookieService.cpp for details
* network.cookie.lifetimePolicy
* - determines how long cookies are stored:
* 0 means keep cookies until they expire
@ -381,25 +382,20 @@ var gPrivacyPane = {
readAcceptCookies: function ()
{
var pref = document.getElementById("network.cookie.cookieBehavior");
var acceptThirdParty = document.getElementById("acceptThirdParty");
var acceptThirdPartyLabel = document.getElementById("acceptThirdPartyLabel");
var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu");
var keepUntil = document.getElementById("keepUntil");
var menu = document.getElementById("keepCookiesUntil");
// enable the rest of the UI for anything other than "disable all cookies"
var acceptCookies = (pref.value != 2);
acceptThirdParty.disabled = !acceptCookies;
acceptThirdPartyLabel.disabled = acceptThirdPartyMenu.disabled = !acceptCookies;
keepUntil.disabled = menu.disabled = this._autoStartPrivateBrowsing || !acceptCookies;
return acceptCookies;
},
readAcceptThirdPartyCookies: function ()
{
var pref = document.getElementById("network.cookie.cookieBehavior");
return pref.value == 0;
},
/**
* Enables/disables the "keep until" label and menulist in response to the
* "accept cookies" checkbox being checked or unchecked.
@ -407,20 +403,50 @@ var gPrivacyPane = {
writeAcceptCookies: function ()
{
var accept = document.getElementById("acceptCookies");
var acceptThirdParty = document.getElementById("acceptThirdParty");
var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu");
// if we're enabling cookies, automatically check 'accept third party'
// if we're enabling cookies, automatically select 'accept third party from visited'
if (accept.checked)
acceptThirdParty.checked = true;
acceptThirdPartyMenu.selectedIndex = 1;
return accept.checked ? (acceptThirdParty.checked ? 0 : 1) : 2;
return accept.checked ? 3 : 2;
},
/**
* Converts between network.cookie.cookieBehavior and the third-party cookie UI
*/
readAcceptThirdPartyCookies: function ()
{
var pref = document.getElementById("network.cookie.cookieBehavior");
switch (pref.value)
{
case 0:
return "always";
case 1:
return "never";
case 2:
return "never";
case 3:
return "visited";
default:
return undefined;
}
},
writeAcceptThirdPartyCookies: function ()
{
var accept = document.getElementById("acceptCookies");
var acceptThirdParty = document.getElementById("acceptThirdParty");
return accept.checked ? (acceptThirdParty.checked ? 0 : 1) : 2;
var accept = document.getElementById("acceptThirdPartyMenu").selectedItem;
switch (accept.value)
{
case "always":
return 0;
case "visited":
return 3;
case "never":
return 1;
default:
return undefined;
}
},
/**

View File

@ -170,11 +170,19 @@
label="&cookieExceptions.label;" accesskey="&cookieExceptions.accesskey;"
preference="pref.privacy.disable_button.cookie_exceptions"/>
</hbox>
<checkbox id="acceptThirdParty" label="&acceptThirdParty.label;" class="indent"
preference="network.cookie.cookieBehavior"
accesskey="&acceptThirdParty.accesskey;"
onsyncfrompreference="return gPrivacyPane.readAcceptThirdPartyCookies();"
onsynctopreference="return gPrivacyPane.writeAcceptThirdPartyCookies();"/>
<hbox id="acceptThirdPartyRow" class="indent">
<label id="acceptThirdPartyLabel" control="acceptThirdPartyMenu"
accesskey="&acceptThirdParty.pre.accesskey;">&acceptThirdParty.pre.label;</label>
<menulist id="acceptThirdPartyMenu" preference="network.cookie.cookieBehavior"
onsyncfrompreference="return gPrivacyPane.readAcceptThirdPartyCookies();"
onsynctopreference="return gPrivacyPane.writeAcceptThirdPartyCookies();">
<menupopup>
<menuitem label="&acceptThirdParty.always.label;" value="always"/>
<menuitem label="&acceptThirdParty.visited.label;" value="visited"/>
<menuitem label="&acceptThirdParty.never.label;" value="never"/>
</menupopup>
</menulist>
</hbox>
<hbox id="keepRow" class="indent">
<label id="keepUntil"
control="keepCookiesUntil"

View File

@ -15,8 +15,8 @@ function test() {
run_test_subset([
test_custom_retention("acceptCookies", "remember"),
test_custom_retention("acceptCookies", "custom"),
test_custom_retention("acceptThirdParty", "remember"),
test_custom_retention("acceptThirdParty", "custom"),
test_custom_retention("acceptThirdPartyMenu", "remember", "always"),
test_custom_retention("acceptThirdPartyMenu", "custom", "visited"),
test_custom_retention("keepCookiesUntil", "remember", 1),
test_custom_retention("keepCookiesUntil", "custom", 2),
test_custom_retention("keepCookiesUntil", "custom", 0),

View File

@ -59,7 +59,8 @@ function test_dependent_elements(win) {
});
let independents = [
win.document.getElementById("acceptCookies"),
win.document.getElementById("acceptThirdParty"),
win.document.getElementById("acceptThirdPartyLabel"),
win.document.getElementById("acceptThirdPartyMenu")
];
independents.forEach(function(control) {
ok(control, "the independent controls should exist");
@ -124,7 +125,8 @@ function test_dependent_cookie_elements(win) {
let pbautostart = win.document.getElementById("privateBrowsingAutoStart");
ok(pbautostart, "the private browsing auto-start checkbox should exist");
let controls = [
win.document.getElementById("acceptThirdParty"),
win.document.getElementById("acceptThirdPartyLabel"),
win.document.getElementById("acceptThirdPartyMenu"),
win.document.getElementById("keepUntil"),
win.document.getElementById("keepCookiesUntil"),
];
@ -210,18 +212,22 @@ function test_dependent_prefs(win) {
let controls = [
win.document.getElementById("rememberHistory"),
win.document.getElementById("rememberForms"),
win.document.getElementById("acceptCookies"),
win.document.getElementById("acceptThirdParty"),
win.document.getElementById("acceptCookies")
];
controls.forEach(function(control) {
ok(control, "the micro-management controls should exist");
});
let thirdPartyCookieMenu = win.document.getElementById("acceptThirdPartyMenu");
ok(thirdPartyCookieMenu, "the third-party cookie control should exist");
function expect_checked(checked) {
controls.forEach(function(control) {
is(control.checked, checked,
control.getAttribute("id") + " should " + (checked ? "not " : "") + "be checked");
});
is(thirdPartyCookieMenu.value == "always" || thirdPartyCookieMenu.value == "visited", checked, "third-party cookies should " + (checked ? "not " : "") + "be limited");
}
// controls should be checked in remember mode
@ -232,6 +238,8 @@ function test_dependent_prefs(win) {
// even if they're unchecked in custom mode
historymode.value = "custom";
controlChanged(historymode);
thirdPartyCookieMenu.value = "never";
controlChanged(thirdPartyCookieMenu);
controls.forEach(function(control) {
control.checked = false;
controlChanged(control);

View File

@ -182,8 +182,8 @@ var gPrivacyPane = {
// select the remember forms history option
document.getElementById("browser.formfill.enable").value = true;
// select the accept cookies option
document.getElementById("network.cookie.cookieBehavior").value = 0;
// select the limit cookies option
document.getElementById("network.cookie.cookieBehavior").value = 3;
// select the cookie lifetime policy option
document.getElementById("network.cookie.lifetimePolicy").value = 0;
@ -366,9 +366,10 @@ var gPrivacyPane = {
* network.cookie.cookieBehavior
* - determines how the browser should handle cookies:
* 0 means enable all cookies
* 1 means reject third party cookies; see
* netwerk/cookie/src/nsCookieService.cpp for a hairier definition
* 1 means reject all third party cookies
* 2 means disable all cookies
* 3 means reject third party cookies unless at least one is already set for the eTLD
* see netwerk/cookie/src/nsCookieService.cpp for details
* network.cookie.lifetimePolicy
* - determines how long cookies are stored:
* 0 means keep cookies until they expire
@ -384,25 +385,20 @@ var gPrivacyPane = {
readAcceptCookies: function ()
{
var pref = document.getElementById("network.cookie.cookieBehavior");
var acceptThirdParty = document.getElementById("acceptThirdParty");
var acceptThirdPartyLabel = document.getElementById("acceptThirdPartyLabel");
var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu");
var keepUntil = document.getElementById("keepUntil");
var menu = document.getElementById("keepCookiesUntil");
// enable the rest of the UI for anything other than "disable all cookies"
var acceptCookies = (pref.value != 2);
acceptThirdParty.disabled = !acceptCookies;
acceptThirdPartyLabel.disabled = acceptThirdPartyMenu.disabled = !acceptCookies;
keepUntil.disabled = menu.disabled = this._autoStartPrivateBrowsing || !acceptCookies;
return acceptCookies;
},
readAcceptThirdPartyCookies: function ()
{
var pref = document.getElementById("network.cookie.cookieBehavior");
return pref.value == 0;
},
/**
* Enables/disables the "keep until" label and menulist in response to the
* "accept cookies" checkbox being checked or unchecked.
@ -410,20 +406,50 @@ var gPrivacyPane = {
writeAcceptCookies: function ()
{
var accept = document.getElementById("acceptCookies");
var acceptThirdParty = document.getElementById("acceptThirdParty");
var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu");
// if we're enabling cookies, automatically check 'accept third party'
// if we're enabling cookies, automatically select 'accept third party from visited'
if (accept.checked)
acceptThirdParty.checked = true;
acceptThirdPartyMenu.selectedIndex = 1;
return accept.checked ? (acceptThirdParty.checked ? 0 : 1) : 2;
return accept.checked ? 3 : 2;
},
/**
* Converts between network.cookie.cookieBehavior and the third-party cookie UI
*/
readAcceptThirdPartyCookies: function ()
{
var pref = document.getElementById("network.cookie.cookieBehavior");
switch (pref.value)
{
case 0:
return "always";
case 1:
return "never";
case 2:
return "never";
case 3:
return "visited";
default:
return undefined;
}
},
writeAcceptThirdPartyCookies: function ()
{
var accept = document.getElementById("acceptCookies");
var acceptThirdParty = document.getElementById("acceptThirdParty");
return accept.checked ? (acceptThirdParty.checked ? 0 : 1) : 2;
var accept = document.getElementById("acceptThirdPartyMenu").selectedItem;
switch (accept.value)
{
case "always":
return 0;
case "visited":
return 3;
case "never":
return 1;
default:
return undefined;
}
},
/**
@ -503,7 +529,7 @@ var gPrivacyPane = {
var settingsButton = document.getElementById("clearDataSettings");
var sanitizeOnShutdownPref = document.getElementById("privacy.sanitize.sanitizeOnShutdown");
settingsButton.disabled = !sanitizeOnShutdownPref.value;
settingsButton.disabled = !sanitizeOnShutdownPref.value;
}
};

View File

@ -183,12 +183,23 @@
label="&cookieExceptions.label;" accesskey="&cookieExceptions.accesskey;"
preference="pref.privacy.disable_button.cookie_exceptions"/>
</hbox>
<checkbox id="acceptThirdParty" label="&acceptThirdParty.label;" class="indent"
preference="network.cookie.cookieBehavior"
accesskey="&acceptThirdParty.accesskey;"
onsyncfrompreference="return gPrivacyPane.readAcceptThirdPartyCookies();"
onsynctopreference="return gPrivacyPane.writeAcceptThirdPartyCookies();"/>
<hbox id="acceptThirdPartyRow" class="indent">
<hbox id="acceptThirdPartyBox" align="center">
<label id="acceptThirdPartyLabel" control="acceptThirdPartyMenu"
accesskey="&acceptThirdParty.pre.accesskey;">&acceptThirdParty.pre.label;</label>
<menulist id="acceptThirdPartyMenu" preference="network.cookie.cookieBehavior"
onsyncfrompreference="return gPrivacyPane.readAcceptThirdPartyCookies();"
onsynctopreference="return gPrivacyPane.writeAcceptThirdPartyCookies();">
<menupopup>
<menuitem label="&acceptThirdParty.always.label;" value="always"/>
<menuitem label="&acceptThirdParty.visited.label;" value="visited"/>
<menuitem label="&acceptThirdParty.never.label;" value="never"/>
</menupopup>
</menulist>
</hbox>
</hbox>
<hbox id="keepRow" class="indent">
<hbox id="keepBox" align="center">
<label id="keepUntil"

View File

@ -2,7 +2,12 @@
* http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
waitForExplicitFinish();
// Allow all cookies, then actually set up the test
SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0]]}, initTest);
}
function initTest() {
const searchTerm = "example";
const dummyTerm = "elpmaxe";

View File

@ -163,6 +163,9 @@ var tests = [
},
function test_all_sites_permission() {
// apply the old default of allowing all cookies
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
// there should be no user-set pref for cookie behavior
is(Services.prefs.getIntPref("network.cookie.cookieBehavior"), PERM_UNKNOWN,
"network.cookie.cookieBehavior is expected default");

View File

@ -16,8 +16,8 @@ function test() {
run_test_subset([
test_custom_retention("acceptCookies", "remember"),
test_custom_retention("acceptCookies", "custom"),
test_custom_retention("acceptThirdParty", "remember"),
test_custom_retention("acceptThirdParty", "custom"),
test_custom_retention("acceptThirdPartyMenu", "remember", "always"),
test_custom_retention("acceptThirdPartyMenu", "custom", "visited"),
test_custom_retention("keepCookiesUntil", "remember", 1),
test_custom_retention("keepCookiesUntil", "custom", 2),
test_custom_retention("keepCookiesUntil", "custom", 0),

View File

@ -69,7 +69,8 @@ function test_dependent_elements(win) {
});
let independents = [
win.document.getElementById("acceptCookies"),
win.document.getElementById("acceptThirdParty"),
win.document.getElementById("acceptThirdPartyLabel"),
win.document.getElementById("acceptThirdPartyMenu")
];
independents.forEach(function(control) {
ok(control, "the independent controls should exist");
@ -133,7 +134,8 @@ function test_dependent_cookie_elements(win) {
let pbautostart = win.document.getElementById("privateBrowsingAutoStart");
ok(pbautostart, "the private browsing auto-start checkbox should exist");
let controls = [
win.document.getElementById("acceptThirdParty"),
win.document.getElementById("acceptThirdPartyLabel"),
win.document.getElementById("acceptThirdPartyMenu"),
win.document.getElementById("keepUntil"),
win.document.getElementById("keepCookiesUntil"),
];
@ -220,17 +222,21 @@ function test_dependent_prefs(win) {
win.document.getElementById("rememberHistory"),
win.document.getElementById("rememberForms"),
win.document.getElementById("acceptCookies"),
win.document.getElementById("acceptThirdParty"),
];
controls.forEach(function(control) {
ok(control, "the micro-management controls should exist");
});
let thirdPartyCookieMenu = win.document.getElementById("acceptThirdPartyMenu");
ok(thirdPartyCookieMenu, "the third-party cookie control should exist");
function expect_checked(checked) {
controls.forEach(function(control) {
is(control.checked, checked,
control.getAttribute("id") + " should " + (checked ? "not " : "") + "be checked");
});
is(thirdPartyCookieMenu.value == "always" || thirdPartyCookieMenu.value == "visited", checked, "third-party cookies should " + (checked ? "not " : "") + "be limited");
}
// controls should be checked in remember mode
@ -241,6 +247,8 @@ function test_dependent_prefs(win) {
// even if they're unchecked in custom mode
historymode.value = "custom";
controlChanged(historymode);
thirdPartyCookieMenu.value = "never";
controlChanged(thirdPartyCookieMenu);
controls.forEach(function(control) {
control.checked = false;
controlChanged(control);

View File

@ -13,10 +13,9 @@ include $(topsrcdir)/config/config.mk
EXTRA_COMPONENTS = \
nsSessionStore.manifest \
nsSessionStore.js \
nsSessionStartup.js \
$(NULL)
EXTRA_PP_COMPONENTS := nsSessionStartup.js
JS_MODULES_PATH := $(FINAL_TARGET)/modules/sessionstore
EXTRA_JS_MODULES := \

View File

@ -72,8 +72,11 @@ SessionStartup.prototype = {
*/
init: function sss_init() {
// do not need to initialize anything in auto-started private browsing sessions
if (PrivateBrowsingUtils.permanentPrivateBrowsing)
if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
this._initialized = true;
gOnceInitializedDeferred.resolve();
return;
}
_SessionFile.read().then(
this._onSessionFileRead.bind(this)

View File

@ -3,8 +3,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function test() {
TestRunner.run();
}
function runTests() {
/** Test (B) for Bug 248970 **/
waitForExplicitFinish();
// Let runTests() be a generator function.
yield executeSoon(next);
let windowsToClose = [];
let file = Services.dirsvc.get("TmpD", Ci.nsIFile);
@ -157,7 +163,7 @@ function test() {
aWin.gBrowser.removeTab(tab_C);
aWin.gBrowser.removeTab(tab_B);
finish();
next();
});
});
});

View File

@ -4,6 +4,7 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --enable-update-packaging
ac_add_options --with-l10n-base=../../l10n-central
ac_add_options --enable-metro
ac_add_options --with-windows-version=601
export MOZILLA_OFFICIAL=1

View File

@ -4,11 +4,17 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const BRAND_SHORT_NAME = Cc["@mozilla.org/intl/stringbundle;1"]
.getService(Ci.nsIStringBundleService)
.createBundle("chrome://branding/locale/brand.properties")
.GetStringFromName("brandShortName");
this.EXPORTED_SYMBOLS = [ "CmdAddonFlags", "CmdCommands" ];
Cu.import("resource:///modules/devtools/gcli.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/osfile.jsm")
XPCOMUtils.defineLazyModuleGetter(this, "gDevTools",
"resource:///modules/devtools/gDevTools.jsm");
@ -768,59 +774,86 @@ XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
return;
}
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
dir.initWithPath(dirName);
if (!dir.exists() || !dir.isDirectory()) {
throw new Error('\'' + dirName + '\' is not a directory.');
}
let en = dir.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator);
while (true) {
let file = en.nextFile;
if (!file) {
break;
let promise = OS.File.stat(dirName);
promise = promise.then(
function onSuccess(stat) {
if (!stat.isDir) {
throw new Error('\'' + dirName + '\' is not a directory.');
} else {
return dirName;
}
},
function onFailure(reason) {
if (reason instanceof OS.File.Error && reason.becauseNoSuchFile) {
throw new Error('\'' + dirName + '\' does not exist.');
} else {
throw reason;
}
}
if (file.leafName.match(/.*\.mozcmd$/) && file.isFile() && file.isReadable()) {
loadCommandFile(file, aSandboxPrincipal);
);
promise.then(
function onSuccess() {
let iterator = new OS.File.DirectoryIterator(dirName);
let iterPromise = iterator.forEach(
function onEntry(entry) {
if (entry.name.match(/.*\.mozcmd$/) && !entry.isDir) {
loadCommandFile(entry, aSandboxPrincipal);
}
}
);
iterPromise.then(
function onSuccess() {
iterator.close();
},
function onFailure(reason) {
iterator.close();
throw reason;
}
);
}
}
},
);
}
};
/**
* Load the commands from a single file
* @param nsIFile aFile The file containing the commands that we should read
* @param OS.File.DirectoryIterator.Entry aFileEntry The DirectoryIterator
* Entry of the file containing the commands that we should read
* @param nsIPrincipal aSandboxPrincipal Scope object for the Sandbox in which
* we eval the script from the .mozcmd file. This should be a chrome window.
*/
function loadCommandFile(aFile, aSandboxPrincipal) {
NetUtil.asyncFetch(aFile, function refresh_fetch(aStream, aStatus) {
if (!Components.isSuccessCode(aStatus)) {
console.error("NetUtil.asyncFetch(" + aFile.path + ",..) failed. Status=" + aStatus);
return;
function loadCommandFile(aFileEntry, aSandboxPrincipal) {
let promise = OS.File.read(aFileEntry.path);
promise = promise.then(
function onSuccess(array) {
let decoder = new TextDecoder();
let source = decoder.decode(array);
let sandbox = new Cu.Sandbox(aSandboxPrincipal, {
sandboxPrototype: aSandboxPrincipal,
wantXrays: false,
sandboxName: aFileEntry.path
});
let data = Cu.evalInSandbox(source, sandbox, "1.8", aFileEntry.name, 1);
if (!Array.isArray(data)) {
console.error("Command file '" + aFileEntry.name + "' does not have top level array.");
return;
}
data.forEach(function(commandSpec) {
gcli.addCommand(commandSpec);
commands.push(commandSpec.name);
});
},
function onError(reason) {
console.error("OS.File.read(" + aFileEntry.path + ") failed.");
throw reason;
}
let source = NetUtil.readInputStreamToString(aStream, aStream.available());
aStream.close();
let sandbox = new Cu.Sandbox(aSandboxPrincipal, {
sandboxPrototype: aSandboxPrincipal,
wantXrays: false,
sandboxName: aFile.path
});
let data = Cu.evalInSandbox(source, sandbox, "1.8", aFile.leafName, 1);
if (!Array.isArray(data)) {
console.error("Command file '" + aFile.leafName + "' does not have top level array.");
return;
}
data.forEach(function(commandSpec) {
gcli.addCommand(commandSpec);
commands.push(commandSpec.name);
});
}.bind(this));
);
}
/**
@ -1763,14 +1796,15 @@ XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
* >> restart --nocache
* - restarts immediately and starts Firefox without using cache
*/
gcli.addCommand({
name: "restart",
description: gcli.lookup("restartFirefoxDesc"),
description: gcli.lookupFormat("restartBrowserDesc", [BRAND_SHORT_NAME]),
params: [
{
name: "nocache",
type: "boolean",
description: gcli.lookup("restartFirefoxNocacheDesc")
description: gcli.lookup("restartBrowserNocacheDesc")
}
],
returnType: "string",
@ -1779,7 +1813,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
.createInstance(Ci.nsISupportsPRBool);
Services.obs.notifyObservers(canceled, "quit-application-requested", "restart");
if (canceled.data) {
return gcli.lookup("restartFirefoxRequestCancelled");
return gcli.lookup("restartBrowserRequestCancelled");
}
// disable loading content from cache.
@ -1791,7 +1825,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
Cc['@mozilla.org/toolkit/app-startup;1']
.getService(Ci.nsIAppStartup)
.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart);
return gcli.lookup("restartFirefoxRestarting");
return gcli.lookupFormat("restartBrowserRestarting", [BRAND_SHORT_NAME]);
}
});
}(this));
@ -1834,8 +1868,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
{
name: "chrome",
type: "boolean",
description: gcli.lookup("screenshotChromeDesc"),
manual: gcli.lookup("screenshotChromeManual")
description: gcli.lookupFormat("screenshotChromeDesc", [BRAND_SHORT_NAME]),
manual: gcli.lookupFormat("screenshotChromeManual", [BRAND_SHORT_NAME])
},
{
name: "delay",

View File

@ -223,13 +223,23 @@ exports.StringType = StringType;
/**
* We don't currently plan to distinguish between integers and floats
* We distinguish between integers and floats with the _allowFloat flag.
*/
function NumberType(typeSpec) {
// Default to integer values
this._allowFloat = !!typeSpec.allowFloat;
if (typeSpec) {
this._min = typeSpec.min;
this._max = typeSpec.max;
this._step = typeSpec.step || 1;
if (!this._allowFloat &&
(this._isFloat(this._min) ||
this._isFloat(this._max) ||
this._isFloat(this._step))) {
throw new Error('allowFloat is false, but non-integer values given in type spec');
}
}
else {
this._step = 1;
@ -274,7 +284,19 @@ NumberType.prototype.parse = function(arg) {
return new Conversion(undefined, arg, Status.INCOMPLETE, '');
}
var value = parseInt(arg.text, 10);
if (!this._allowFloat && (arg.text.indexOf('.') !== -1)) {
return new Conversion(undefined, arg, Status.ERROR,
l10n.lookupFormat('typesNumberNotInt', [ arg.text ]));
}
var value;
if (this._allowFloat) {
value = parseFloat(arg.text);
}
else {
value = parseInt(arg.text, 10);
}
if (isNaN(value)) {
return new Conversion(undefined, arg, Status.ERROR,
l10n.lookupFormat('typesNumberNan', [ arg.text ]));
@ -336,6 +358,14 @@ NumberType.prototype._boundsCheck = function(value) {
return value;
};
/**
* Return true if the given value is a finite number and not an integer, else
* return false.
*/
NumberType.prototype._isFloat = function(value) {
return ((typeof value === 'number') && isFinite(value) && (value % 1 !== 0));
};
NumberType.prototype.name = 'number';
exports.NumberType = NumberType;

View File

@ -324,6 +324,52 @@ exports.testSingleNumber = function() {
assert.is('tsu', requ.commandAssignment.value.name);
assert.is('x', assign1.arg.text);
assert.is(undefined, assign1.value);
update({ typed: 'tsu 1.5', cursor: { start: 7, end: 7 } });
assert.is( 'VVVVEEE', statuses);
assert.is(Status.ERROR, status);
assert.is('tsu', requ.commandAssignment.value.name);
assert.is('1.5', assign1.arg.text);
assert.is(undefined, assign1.value);
};
exports.testSingleFloat = function() {
update({ typed: 'tsf', cursor: { start: 3, end: 3 } });
assert.is( 'VVV', statuses);
assert.is(Status.ERROR, status);
assert.is('tsf', requ.commandAssignment.value.name);
assert.is('', assign1.arg.text);
assert.is(undefined, assign1.value);
update({ typed: 'tsf ', cursor: { start: 4, end: 4 } });
assert.is( 'VVVV', statuses);
assert.is(Status.ERROR, status);
assert.is('tsf', requ.commandAssignment.value.name);
assert.is('', assign1.arg.text);
assert.is(undefined, assign1.value);
update({ typed: 'tsf 1', cursor: { start: 5, end: 5 } });
assert.is( 'VVVVV', statuses);
assert.is(Status.VALID, status);
assert.is('tsf', requ.commandAssignment.value.name);
assert.is('1', assign1.arg.text);
assert.is(1, assign1.value);
assert.is('number', typeof assign1.value);
update({ typed: 'tsf x', cursor: { start: 5, end: 5 } });
assert.is( 'VVVVE', statuses);
assert.is(Status.ERROR, status);
assert.is('tsf', requ.commandAssignment.value.name);
assert.is('x', assign1.arg.text);
assert.is(undefined, assign1.value);
update({ typed: 'tsf 1.5', cursor: { start: 7, end: 7 } });
assert.is( 'VVVVVVV', statuses);
assert.is(Status.VALID, status);
assert.is('tsf', requ.commandAssignment.value.name);
assert.is('1.5', assign1.arg.text);
assert.is(1.5, assign1.value);
assert.is('number', typeof assign1.value);
};
exports.testElement = function(options) {

View File

@ -203,6 +203,34 @@ exports.testIncrDecr = function() {
check('tsu 10', KEY_DOWNS_TO, 'tsu 9');
check('tsu 100', KEY_DOWNS_TO, 'tsu 10');
check('tsf -70', KEY_UPS_TO, 'tsf -6.5');
check('tsf -6.5', KEY_UPS_TO, 'tsf -6');
check('tsf -6', KEY_UPS_TO, 'tsf -4.5');
check('tsf -4.5', KEY_UPS_TO, 'tsf -3');
check('tsf -4', KEY_UPS_TO, 'tsf -3');
check('tsf -3', KEY_UPS_TO, 'tsf -1.5');
check('tsf -1.5', KEY_UPS_TO, 'tsf 0');
check('tsf 0', KEY_UPS_TO, 'tsf 1.5');
check('tsf 1.5', KEY_UPS_TO, 'tsf 3');
check('tsf 2', KEY_UPS_TO, 'tsf 3');
check('tsf 3', KEY_UPS_TO, 'tsf 4.5');
check('tsf 5', KEY_UPS_TO, 'tsf 6');
check('tsf 100', KEY_UPS_TO, 'tsf -6.5');
check('tsf -70', KEY_DOWNS_TO, 'tsf 11.5');
check('tsf -6.5', KEY_DOWNS_TO, 'tsf -6.5');
check('tsf -6', KEY_DOWNS_TO, 'tsf -6.5');
check('tsf -4.5', KEY_DOWNS_TO, 'tsf -6');
check('tsf -4', KEY_DOWNS_TO, 'tsf -4.5');
check('tsf -3', KEY_DOWNS_TO, 'tsf -4.5');
check('tsf -1.5', KEY_DOWNS_TO, 'tsf -3');
check('tsf 0', KEY_DOWNS_TO, 'tsf -1.5');
check('tsf 1.5', KEY_DOWNS_TO, 'tsf 0');
check('tsf 2', KEY_DOWNS_TO, 'tsf 1.5');
check('tsf 3', KEY_DOWNS_TO, 'tsf 1.5');
check('tsf 5', KEY_DOWNS_TO, 'tsf 4.5');
check('tsf 100', KEY_DOWNS_TO, 'tsf 11.5');
// Bug 707007 - GCLI increment and decrement operations cycle through
// selection options in the wrong order
check('tselarr 1', KEY_DOWNS_TO, 'tselarr 2');

View File

@ -60,6 +60,11 @@ exports.shutdown = function(options) {
};
exports.testPredictions = function(options) {
if (options.isJsdom) {
assert.log('Skipping checks due to jsdom document.stylsheets support.');
return;
}
var resource1 = types.getType('resource');
var options1 = resource1.getLookup();
// firefox doesn't support digging into scripts/stylesheets
@ -67,7 +72,7 @@ exports.testPredictions = function(options) {
assert.ok(options1.length > 1, 'have all resources');
}
else {
assert.log('Skipping checks due to jsdom/firefox document.stylsheets support.');
assert.log('Skipping checks due to firefox document.stylsheets support.');
}
options1.forEach(function(prediction) {
checkPrediction(resource1, prediction);
@ -80,7 +85,7 @@ exports.testPredictions = function(options) {
assert.ok(options2.length > 1, 'have js resources');
}
else {
assert.log('Skipping checks due to jsdom/firefox document.stylsheets support.');
assert.log('Skipping checks due to firefox document.stylsheets support.');
}
options2.forEach(function(prediction) {
checkPrediction(resource2, prediction);
@ -93,7 +98,7 @@ exports.testPredictions = function(options) {
assert.ok(options3.length >= 1, 'have css resources');
}
else {
assert.log('Skipping checks due to jsdom/firefox document.stylsheets support.');
assert.log('Skipping checks due to firefox document.stylsheets support.');
}
options3.forEach(function(prediction) {
checkPrediction(resource3, prediction);

View File

@ -114,10 +114,10 @@ exports.testActivate = function(options) {
options: [ 'true' ]
}, options);
type('asdf', {
type('wxqy', {
important: false,
options: [ ],
error: 'Can\'t use \'asdf\'.'
error: 'Can\'t use \'wxqy\'.'
}, options);
type('', { }, options);

View File

@ -72,6 +72,7 @@ mockCommands.setup = function() {
canon.addCommand(mockCommands.tsb);
canon.addCommand(mockCommands.tss);
canon.addCommand(mockCommands.tsu);
canon.addCommand(mockCommands.tsf);
canon.addCommand(mockCommands.tsn);
canon.addCommand(mockCommands.tsnDif);
canon.addCommand(mockCommands.tsnExt);
@ -99,6 +100,7 @@ mockCommands.shutdown = function() {
canon.removeCommand(mockCommands.tsb);
canon.removeCommand(mockCommands.tss);
canon.removeCommand(mockCommands.tsu);
canon.removeCommand(mockCommands.tsf);
canon.removeCommand(mockCommands.tsn);
canon.removeCommand(mockCommands.tsnDif);
canon.removeCommand(mockCommands.tsnExt);
@ -231,6 +233,12 @@ mockCommands.tsu = {
exec: createExec('tsu')
};
mockCommands.tsf = {
name: 'tsf',
params: [ { name: 'num', type: { name: 'number', allowFloat: true, max: 11.5, min: -6.5, step: 1.5 } } ],
exec: createExec('tsf')
};
mockCommands.tsn = {
name: 'tsn'
};

View File

@ -4,6 +4,11 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const BRAND_SHORT_NAME = Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService).
createBundle("chrome://branding/locale/brand.properties").
GetStringFromName("brandShortName");
this.EXPORTED_SYMBOLS = [ ];
Cu.import("resource:///modules/devtools/gcli.jsm");
@ -17,14 +22,14 @@ gcli.addCommand({
gcli.addCommand({
name: 'resize on',
description: gcli.lookup('resizeModeOnDesc'),
manual: gcli.lookup('resizeModeManual'),
manual: gcli.lookupFormat('resizeModeManual', [BRAND_SHORT_NAME]),
exec: gcli_cmd_resize
});
gcli.addCommand({
name: 'resize off',
description: gcli.lookup('resizeModeOffDesc'),
manual: gcli.lookup('resizeModeManual'),
manual: gcli.lookupFormat('resizeModeManual', [BRAND_SHORT_NAME]),
exec: gcli_cmd_resize
});
@ -34,7 +39,7 @@ gcli.addCommand({
buttonClass: "command-button",
tooltipText: gcli.lookup("resizeModeToggleTooltip"),
description: gcli.lookup('resizeModeToggleDesc'),
manual: gcli.lookup('resizeModeManual'),
manual: gcli.lookupFormat('resizeModeManual', [BRAND_SHORT_NAME]),
state: {
isChecked: function(aTarget) {
let browserWindow = aTarget.tab.ownerDocument.defaultView;

View File

@ -747,6 +747,7 @@ bin/libfreebl_32int64_3.so
#ifdef MOZ_METRO
@BINPATH@/components/MetroUIUtils.js
@BINPATH@/components/MetroUIUtils.manifest
[metro]
; gre resources
@BINPATH@/CommandExecuteHandler@BIN_SUFFIX@

View File

@ -92,6 +92,10 @@ typesNumberMax=%1$S is greater than maximum allowed: %2$S.
# message is displayed.
typesNumberMin=%1$S is smaller than minimum allowed: %2$S.
# LOCALIZATION NOTE (typesNumberNotInt): When the command line is passed a
# number, but the number has a decimal part and floats are not allowed.
typesNumberNotInt='%S' must be an integer.
# LOCALIZATION NOTE (typesSelectionNomatch): When the command line is passed
# an option with a limited number of correct values, but the passed value is
# not one of them, this error message is displayed.
@ -333,7 +337,7 @@ introManual=Redisplay the message that is shown to new users until they click th
# first opens the developer toolbar to explain the command line, and is shown
# each time it is opened until the user clicks the 'Got it!' button. This
# string is the opening paragraph of the intro text.
introTextOpening=The Firefox command line is designed for developers. It focuses on speed of input over JavaScript syntax and a rich display over monospace output.
introTextOpening=This command line is designed for developers. It focuses on speed of input over JavaScript syntax and a rich display over monospace output.
# LOCALIZATION NOTE (introTextCommands): For information about the 'intro
# text' see introTextOpening. The second paragraph is in 2 sections, the first

View File

@ -73,12 +73,14 @@ screenshotClipboardManual=True if you want to copy the screenshot instead of sav
# LOCALIZATION NOTE (screenshotChromeDesc) A very short string to describe
# the 'chrome' parameter to the 'screenshot' command, which is displayed in
# a dialog when the user is using this command.
screenshotChromeDesc=Capture Firefox chrome window? (true/false)
# The argument (%1$S) is the browser name.
screenshotChromeDesc=Capture %1$S chrome window? (true/false)
# LOCALIZATION NOTE (screenshotChromeManual) A fuller description of the
# 'chrome' parameter to the 'screenshot' command, displayed when the user
# asks for help on what it does.
screenshotChromeManual=True if you want to take the screenshot of the Firefox window rather than the web page's content window.
# The argument (%1$S) is the browser name.
screenshotChromeManual=True if you want to take the screenshot of the %1$S window rather than the web page's content window.
# LOCALIZATION NOTE (screenshotGroupOptions) A label for the optional options of
# the screenshot command.
@ -131,23 +133,25 @@ screenshotErrorCopying=Error occurred while copying to clipboard.
# screenshot is successfully copied to the clipboard.
screenshotCopied=Copied to clipboard.
# LOCALIZATION NOTE (restartFirefoxDesc) A very short description of the
# LOCALIZATION NOTE (restartBrowserDesc) A very short description of the
# 'restart' command. This string is designed to be shown in a menu alongside the
# command name, which is why it should be as short as possible.
restartFirefoxDesc=Restart Firefox
# The argument (%1$S) is the browser name.
restartBrowserDesc=Restart %1$S
# LOCALIZATION NOTE (restartFirefoxNocacheDesc) A very short string to
# LOCALIZATION NOTE (restartBrowserNocacheDesc) A very short string to
# describe the 'nocache' parameter to the 'restart' command, which is
# displayed in a dialog when the user is using this command.
restartFirefoxNocacheDesc=Disables loading content from cache upon restart
restartBrowserNocacheDesc=Disables loading content from cache upon restart
# LOCALIZATION NOTE (restartFirefoxRequestCancelled) A string displayed to the
# LOCALIZATION NOTE (restartBrowserRequestCancelled) A string displayed to the
# user when a scheduled restart has been aborted by the user.
restartFirefoxRequestCancelled=Restart request cancelled by user.
restartBrowserRequestCancelled=Restart request cancelled by user.
# LOCALIZATION NOTE (restartFirefoxRestarting) A string displayed to the
# LOCALIZATION NOTE (restartBrowserRestarting) A string displayed to the
# user when a restart has been initiated without a delay.
restartFirefoxRestarting=Restarting Firefox…
# The argument (%1$S) is the browser name.
restartBrowserRestarting=Restarting %1$S…
# LOCALIZATION NOTE (inspectDesc) A very short description of the 'inspect'
# command. See inspectManual for a fuller description of what it does. This
@ -504,7 +508,8 @@ resizeModeDesc=Control Responsive Design Mode
# LOCALIZATION NOTE (resizeModeManual) A fuller description of the 'resize'
# command, displayed when the user asks for help on what it does.
resizeModeManual=Responsive websites respond to their environment, so they look good on a mobile display, a cinema display and everything in-between. Responsive Design Mode allows you to easily test a variety of page sizes in Firefox without needing to resize your whole browser.
# The argument (%1$S) is the browser name.
resizeModeManual=Responsive websites respond to their environment, so they look good on a mobile display, a cinema display and everything in-between. Responsive Design Mode allows you to easily test a variety of page sizes in %1$S without needing to resize your whole browser.
# LOCALIZATION NOTE (cmdDesc) A very short description of the 'cmd'
# command. This string is designed to be shown in a menu alongside the command

View File

@ -27,8 +27,11 @@
<!ENTITY acceptCookies.label "Accept cookies from sites">
<!ENTITY acceptCookies.accesskey "A">
<!ENTITY acceptThirdParty.label "Accept third-party cookies">
<!ENTITY acceptThirdParty.accesskey "c">
<!ENTITY acceptThirdParty.pre.label "Accept third-party cookies:">
<!ENTITY acceptThirdParty.pre.accesskey "c">
<!ENTITY acceptThirdParty.always.label "Always">
<!ENTITY acceptThirdParty.never.label "Never">
<!ENTITY acceptThirdParty.visited.label "From visited">
<!ENTITY keepUntil.label "Keep until:">
<!ENTITY keepUntil.accesskey "K">

View File

@ -8,7 +8,6 @@ all = browser/locales/all-locales
[compare]
dirs = browser
browser/metro
extensions/reporter
other-licenses/branding/firefox
browser/branding/official

View File

@ -79,18 +79,18 @@ fi
if [ "$MOZ_WIDGET_TOOLKIT" = "gtk2" -o "$MOZ_WIDGET_TOOLKIT" = "qt" ]; then
add_makefiles "
browser/themes/gnomestripe/Makefile
browser/themes/gnomestripe/communicator/Makefile
browser/themes/linux/Makefile
browser/themes/linux/communicator/Makefile
"
elif [ "$MOZ_WIDGET_TOOLKIT" = "cocoa" ]; then
add_makefiles "
browser/themes/pinstripe/Makefile
browser/themes/pinstripe/communicator/Makefile
browser/themes/osx/Makefile
browser/themes/osx/communicator/Makefile
"
else
add_makefiles "
browser/themes/winstripe/Makefile
browser/themes/winstripe/communicator/Makefile
browser/themes/windows/Makefile
browser/themes/windows/communicator/Makefile
"
fi

View File

@ -145,6 +145,7 @@
<key id="key_findPrevious2" key="g" modifiers="accel,shift" command="cmd_findPrevious"/>
<key id="key_quit" key="q" modifiers="accel" command="cmd_quit"/>
<key id="key_addBoomkark" key="d" modifiers="accel" command="cmd_addBookmark"/>
<key id="key_console" key="j" modifiers="accel,shift" oncommand="PanelUI.show('console-container')"/>
<!-- manage tabs -->
<key id="key_newTab" key="t" modifiers="accel" command="cmd_newTab"/>

View File

@ -80,15 +80,20 @@ function handleRequest(aSubject, aTopic, aData) {
function (error) {
// bug 827146 -- In the future, the UI should catch NO_DEVICES_FOUND
// and allow the user to plug in a device, instead of immediately failing.
let msg = Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString);
msg.data = error;
Services.obs.notifyObservers(msg, "getUserMedia:response:deny", callID);
Cu.reportError(error);
denyRequest(callID, error);
}
);
}
function denyRequest(aCallID, aError) {
let msg = null;
if (aError) {
msg = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
msg.data = aError;
}
Services.obs.notifyObservers(msg, "getUserMedia:response:deny", aCallID);
}
function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
let audioDevices = [];
let videoDevices = [];
@ -113,8 +118,10 @@ function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
requestType = "Microphone";
else if (videoDevices.length)
requestType = "Camera";
else
else {
denyRequest(aCallID, "NO_DEVICES_FOUND");
return;
}
let host = aBrowser.contentDocument.documentURIObject.asciiHost;
let chromeDoc = aBrowser.ownerDocument;
@ -173,7 +180,7 @@ function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
}
if (allowedDevices.Count() == 0) {
Services.obs.notifyObservers(null, "getUserMedia:response:deny", aCallID);
denyRequest(aCallID);
return;
}
@ -197,7 +204,7 @@ function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
label: stringBundle.getString("getUserMedia.denyRequest.label"),
accessKey: stringBundle.getString("getUserMedia.denyRequest.accesskey"),
callback: function () {
Services.obs.notifyObservers(null, "getUserMedia:response:deny", aCallID);
denyRequest(aCallID);
}
}];

View File

@ -9,21 +9,13 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
#
# Theme Selection
#
# Windows Winstripe
# GNOME/Linux Gnomestripe
# MacOS X Pinstripe
#
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
DIRS = pinstripe
DIRS = osx
else
DIRS = winstripe
DIRS = windows
endif
ifneq (,$(filter gtk2 qt,$(MOZ_WIDGET_TOOLKIT)))
DIRS = gnomestripe
DIRS = linux
endif
include $(topsrcdir)/config/rules.mk

View File

Before

Width:  |  Height:  |  Size: 606 B

After

Width:  |  Height:  |  Size: 606 B

View File

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

Before

Width:  |  Height:  |  Size: 573 B

After

Width:  |  Height:  |  Size: 573 B

View File

Before

Width:  |  Height:  |  Size: 767 B

After

Width:  |  Height:  |  Size: 767 B

View File

Before

Width:  |  Height:  |  Size: 822 B

After

Width:  |  Height:  |  Size: 822 B

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

Before

Width:  |  Height:  |  Size: 865 B

After

Width:  |  Height:  |  Size: 865 B

View File

Before

Width:  |  Height:  |  Size: 928 B

After

Width:  |  Height:  |  Size: 928 B

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 791 B

After

Width:  |  Height:  |  Size: 791 B

View File

Before

Width:  |  Height:  |  Size: 776 B

After

Width:  |  Height:  |  Size: 776 B

View File

Before

Width:  |  Height:  |  Size: 767 B

After

Width:  |  Height:  |  Size: 767 B

View File

Before

Width:  |  Height:  |  Size: 405 B

After

Width:  |  Height:  |  Size: 405 B

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