Merge mozilla-central into services-central

This commit is contained in:
Gregory Szorc 2013-01-27 10:05:23 -08:00
Родитель c500a06d34 2a0981338e
Коммит a97dbeda57
880 изменённых файлов: 21771 добавлений и 26956 удалений

Просмотреть файл

@ -13,10 +13,6 @@
* limitations under the License.
*/
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <algorithm>
#include <endian.h>
#include <fcntl.h>
@ -24,13 +20,15 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <vector>
#include "mozilla/Util.h"
#include "mozilla/FileUtils.h"
#include "mozilla/NullPtr.h"
#include "mozilla/Util.h"
#include "png.h"
#include "android/log.h"
#include "ui/FramebufferNativeWindow.h"
#include "hardware_legacy/power.h"
#include "hardware/gralloc.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "Gonk", ## args)
@ -231,9 +229,10 @@ public:
struct AnimationFrame {
char path[256];
char *buf;
uint16_t width;
uint16_t height;
const local_file_header *file;
uint32_t width;
uint32_t height;
uint16_t bytepp;
AnimationFrame() : buf(nullptr) {}
AnimationFrame(const AnimationFrame &frame) : buf(nullptr) {
@ -251,7 +250,7 @@ struct AnimationFrame {
return strcmp(path, other.path) < 0;
}
void ReadPngFrame();
void ReadPngFrame(int outputFormat);
};
struct AnimationPart {
@ -280,8 +279,20 @@ RawReader(png_structp png_ptr, png_bytep data, png_size_t length)
state->offset += length;
}
static void
TransformTo565(png_structp png_ptr, png_row_infop row_info, png_bytep data)
{
uint16_t *outbuf = (uint16_t *)data;
uint8_t *inbuf = (uint8_t *)data;
for (int i = 0; i < row_info->rowbytes; i += 3) {
*outbuf++ = ((inbuf[i] & 0xF8) << 8) |
((inbuf[i + 1] & 0xFC) << 3) |
((inbuf[i + 2] ) >> 3);
}
}
void
AnimationFrame::ReadPngFrame()
AnimationFrame::ReadPngFrame(int outputFormat)
{
png_structp pngread = png_create_read_struct(PNG_LIBPNG_VER_STRING,
nullptr, nullptr, nullptr);
@ -301,52 +312,45 @@ AnimationFrame::ReadPngFrame()
width = png_get_image_width(pngread, pnginfo);
height = png_get_image_height(pngread, pnginfo);
buf = (char *)malloc(width * height * 3);
switch (outputFormat) {
case HAL_PIXEL_FORMAT_BGRA_8888:
png_set_bgr(pngread);
// FALL THROUGH
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
bytepp = 4;
png_set_filler(pngread, 0xFF, PNG_FILLER_AFTER);
break;
case HAL_PIXEL_FORMAT_RGB_888:
bytepp = 3;
png_set_strip_alpha(pngread);
break;
default:
LOGW("Unknown pixel format %d. Assuming RGB 565.", outputFormat);
// FALL THROUGH
case HAL_PIXEL_FORMAT_RGB_565:
bytepp = 2;
png_set_strip_alpha(pngread);
png_set_read_user_transform_fn(pngread, TransformTo565);
break;
}
// An extra row is added to give libpng enough space when
// decoding 3/4 bytepp inputs for 2 bytepp output surfaces
buf = (char *)malloc(width * (height + 1) * bytepp);
vector<char *> rows(height + 1);
uint32_t stride = width * 3;
uint32_t stride = width * bytepp;
for (int i = 0; i < height; i++) {
rows[i] = buf + (stride * i);
}
rows[height] = nullptr;
png_set_strip_16(pngread);
png_set_palette_to_rgb(pngread);
png_read_image(pngread, (png_bytepp)&rows.front());
png_destroy_read_struct(&pngread, &pnginfo, nullptr);
}
static const EGLint kEGLConfigAttribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
static bool
CreateConfig(EGLConfig* aConfig, EGLDisplay display, int format)
{
EGLConfig configs[64];
EGLint ncfg = ArrayLength(configs);
if (!eglChooseConfig(display, kEGLConfigAttribs,
configs, ncfg, &ncfg) ||
ncfg < 1) {
return false;
}
for (int j = 0; j < ncfg; ++j) {
EGLConfig config = configs[j];
EGLint id;
if (eglGetConfigAttrib(display, config,
EGL_NATIVE_VISUAL_ID, &id) &&
id > 0 && id == format)
{
*aConfig = config;
return true;
}
}
return false;
}
static void *
AnimationThread(void *)
{
@ -356,21 +360,6 @@ AnimationThread(void *)
return nullptr;
}
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, nullptr, nullptr);
int format;
ANativeWindow const * const window = gNativeWindow.get();
window->query(window, NATIVE_WINDOW_FORMAT, &format);
EGLConfig config;
if (!CreateConfig(&config, display, format)) {
LOGW("Could not find config for pixel format");
return nullptr;
}
EGLSurface surface = eglCreateWindowSurface(display, config, gNativeWindow.get(), nullptr);
const cdir_entry *entry = nullptr;
const local_file_header *file = nullptr;
while ((entry = reader.GetNextEntry(entry))) {
@ -386,6 +375,18 @@ AnimationThread(void *)
return nullptr;
}
int format;
ANativeWindow *window = gNativeWindow.get();
window->query(window, NATIVE_WINDOW_FORMAT, &format);
hw_module_t const *module;
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module)) {
LOGW("Could not get gralloc module");
return nullptr;
}
gralloc_module_t const *grmodule =
reinterpret_cast<gralloc_module_t const*>(module);
string descCopy;
descCopy.append(file->GetData(), entry->GetDataSize());
int32_t width, height, fps;
@ -452,104 +453,6 @@ AnimationThread(void *)
sort(part.frames.begin(), part.frames.end());
}
static EGLint gContextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE, 0
};
EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, gContextAttribs);
eglMakeCurrent(display, surface, surface, context);
glEnable(GL_TEXTURE_2D);
const char *vsString =
"attribute vec2 aPosition; "
"attribute vec2 aTexCoord; "
"varying vec2 vTexCoord; "
"void main() { "
" gl_Position = vec4(aPosition, 0.0, 1.0); "
" vTexCoord = aTexCoord; "
"}";
const char *fsString =
"precision mediump float; "
"varying vec2 vTexCoord; "
"uniform sampler2D sTexture; "
"void main() { "
" gl_FragColor = vec4(texture2D(sTexture, vTexCoord).rgb, 1.0); "
"}";
GLint status;
GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vsh, 1, &vsString, nullptr);
glCompileShader(vsh);
glGetShaderiv(vsh, GL_COMPILE_STATUS, &status);
if (!status) {
LOGE("Failed to compile vertex shader");
return nullptr;
}
GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fsh, 1, &fsString, nullptr);
glCompileShader(fsh);
glGetShaderiv(fsh, GL_COMPILE_STATUS, &status);
if (!status) {
LOGE("Failed to compile fragment shader");
return nullptr;
}
GLuint programId = glCreateProgram();
glAttachShader(programId, vsh);
glAttachShader(programId, fsh);
glLinkProgram(programId);
glGetProgramiv(programId, GL_LINK_STATUS, &status);
if (!status) {
LOG("Failed to link program");
return nullptr;
}
GLint positionLoc = glGetAttribLocation(programId, "aPosition");
GLint texCoordLoc = glGetAttribLocation(programId, "aTexCoord");
GLint textureLoc = glGetUniformLocation(programId, "sTexture");
glUseProgram(programId);
GLfloat texCoords[] = { 0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 1.0f,
1.0f, 0.0f };
GLfloat vCoords[] = { -1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, -1.0f,
1.0f, 1.0f };
GLuint rectBuf, texBuf;
glGenBuffers(1, &rectBuf);
glGenBuffers(1, &texBuf);
GLuint tex;
glGenTextures(1, &tex);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glEnableVertexAttribArray(positionLoc);
glBindBuffer(GL_ARRAY_BUFFER, rectBuf);
glBufferData(GL_ARRAY_BUFFER, sizeof(vCoords), vCoords, GL_STATIC_DRAW);
glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(texCoordLoc);
glBindBuffer(GL_ARRAY_BUFFER, texBuf);
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW);
glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUniform1i(textureLoc, 0);
uint32_t frameDelayUs = 1000000 / fps;
for (uint32_t i = 0; i < parts.size(); i++) {
@ -562,13 +465,33 @@ AnimationThread(void *)
gettimeofday(&tv1, nullptr);
AnimationFrame &frame = part.frames[k];
if (!frame.buf) {
frame.ReadPngFrame();
frame.ReadPngFrame(format);
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
frame.width, frame.height, 0,
GL_RGB, GL_UNSIGNED_BYTE, frame.buf);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
ANativeWindowBuffer *buf;
if (window->dequeueBuffer(window, &buf)) {
LOGW("Failed to get an ANativeWindowBuffer");
break;
}
if (window->lockBuffer(window, buf)) {
LOGW("Failed to lock ANativeWindowBuffer");
window->queueBuffer(window, buf);
break;
}
void *vaddr;
if (grmodule->lock(grmodule, buf->handle,
GRALLOC_USAGE_SW_READ_NEVER |
GRALLOC_USAGE_SW_WRITE_OFTEN |
GRALLOC_USAGE_HW_FB,
0, 0, width, height, &vaddr)) {
LOGW("Failed to lock buffer_handle_t");
window->queueBuffer(window, buf);
break;
}
memcpy(vaddr, frame.buf,
frame.width * frame.height * frame.bytepp);
grmodule->unlock(grmodule, buf->handle);
gettimeofday(&tv2, nullptr);
@ -580,7 +503,7 @@ AnimationThread(void *)
LOGW("Frame delay is %d us but decoding took %d us", frameDelayUs, tv2.tv_usec);
}
eglSwapBuffers(display, surface);
window->queueBuffer(window, buf);
if (part.count && j >= part.count) {
free(frame.buf);
@ -590,19 +513,7 @@ AnimationThread(void *)
usleep(frameDelayUs * part.pause);
}
}
glBindTexture(GL_TEXTURE_2D, 0);
glUseProgram(0);
glDeleteTextures(1, &tex);
glDeleteBuffers(1, &texBuf);
glDeleteBuffers(1, &rectBuf);
glDeleteProgram(programId);
glDeleteShader(fsh);
glDeleteShader(vsh);
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(display, context);
eglDestroySurface(display, surface);
return nullptr;
}
@ -628,6 +539,21 @@ NativeWindow()
// statements.
set_screen_state(1);
// For some devices, it takes a while for the framebuffer to become
// usable. So we wait until the framebuffer has woken up before we
// try to open it.
{
char buf;
int len = 0;
ScopedClose fd(open("/sys/power/wait_for_fb_wake", O_RDONLY, 0));
do {
len = read(fd.get(), &buf, 1);
} while (len < 0 && errno == EINTR);
if (len < 0) {
LOGE("BootAnimation: wait_for_fb_sleep failed errno: %d", errno);
}
}
// We (apparently) don't have a way to tell if allocating the
// fbs succeeded or failed.
gNativeWindow = new FramebufferNativeWindow();

Просмотреть файл

@ -27,8 +27,6 @@ CPPSRCS = nsBrowserApp.cpp
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
CPPSRCS += BootAnimation.cpp
LIBS += \
-lGLESv2 \
-lEGL \
-lui \
-lhardware_legacy \
-lhardware \

Просмотреть файл

@ -56,6 +56,10 @@ UpdateCheckListener.prototype = {
onCheckComplete: function UCL_onCheckComplete(request, updates, updateCount) {
if (Services.um.activeUpdate) {
// We're actively downloading an update, that's the update the user should
// see, even if a newer update is available.
this._updatePrompt.setUpdateStatus("active-update");
this._updatePrompt.showUpdateAvailable(Services.um.activeUpdate);
return;
}
@ -177,6 +181,14 @@ 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);

Просмотреть файл

@ -7,7 +7,7 @@
},
{
"size": 4139008,
"digest": "b1eac90cebe52708d512bbc293c507da9d93bc8c6a78cbbbd78cc9b7beb2cd335bef9bf8e4bf5a9dc38521f7080d29a743626f9e4af6c42ec211db22dc9d0fda",
"digest": "6f65553e882316582b944e46c659915a1b907c4a326104cb31d81356330dddacba757e3eafbd282063da0e670c3c5d6b9a0905ab88da84b47848d810c37571cb",
"algorithm": "sha512",
"filename": "boot.img"
}

Просмотреть файл

@ -1,13 +1,13 @@
[
{
"size": 832341968,
"digest": "e2d099677f5f930db0b2c03eaf3812a53f02be0773bdb3bad89b1c387041e920c17b90f041bf70d9c2ab715dd4556503534483d4ebc28fb035f41cd5ebba6a52",
"size": 832272360,
"digest": "bb7369106d32a184c61fc8c6658c4d1c64dd778e432a3dd39592b99a92ed0a8f4a9fede60399ec2c85ddaf077f27d77613848b253f0ac155383b23955446396f",
"algorithm": "sha512",
"filename": "gonk.tar.xz"
},
{
"size": 8622080,
"digest": "7a2bbf0c76f7b7d5e4b89f758f69b5d8bcf08ec579374877de8939ad69883ab8cd842f04fdaa03a4ef9cdf8170f242e0381dd437e969d5212ead6cdd6f79ab50",
"digest": "36681be904b20a52dbebf38b86466026430d59adb0e72428ae7557a442d037eb378d278aab181b04a753821ff0a99b6228380d59f86ddd5fbf291284fe54932b",
"algorithm": "sha512",
"filename": "boot.img"
}

Просмотреть файл

@ -5,86 +5,86 @@
<remote fetch="https://android.googlesource.com/" name="aosp"/>
<remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
<remote fetch="git://github.com/mozilla/" name="mozilla"/>
<remote fetch="http://git.mozilla.org/" name="mozillaorg"/>
<remote fetch="git://codeaurora.org/" name="caf"/>
<remote fetch="git://android.git.linaro.org/" name="linaro"/>
<remote fetch="https://git.mozilla.org" name="mozillaorg"/>
<default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="273ba23d5c6c9f6a34995a3cc429804d1449ca9f">
<project name="platform_build" path="build" remote="b2g" revision="0784cdcb29ae45e5bf903cc03fa1bc206162665b">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="654358494ba601a46ef9838debc95417ae464cc6"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="32106d4ea635ebe17a1610b643b398db639b8b97"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="e1bd90051c9e937221eb1f91c94e3cde747311a7"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2f8c7d3546bda16b02a61b422786919875c19f15"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="2d380d27c86263537f6b829cd0238f5dd702c735"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="601fc18b28c9d7cf6954b281ddd3b705c74a9215"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="6ee1f8987ef36d688f97064c003ad57849dfadf2"/>
<!-- Stock Android things -->
<!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<!-- Information: platform/bionic is tagged with M8960AAAAANLYA100715A --><project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
<!-- Information: platform/bootable/recovery is tagged with M8960AAAAANLYA100715A --><project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
<!-- Information: platform/development is tagged with M8960AAAAANLYA100715A --><project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
<!-- Information: device/common is tagged with M8960AAAAANLYA1005304 --><project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
<!-- Information: device/sample is tagged with M8960AAAAANLYA100715A --><project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
<!-- Information: platform/external/apache-http is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/apache-http" path="external/apache-http" revision="6c9d8c58d3ed710f87c26820d903bb8aad81754f"/>
<!-- Information: platform/external/apache-http is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/apache-http" path="external/apache-http" revision="6c9d8c58d3ed710f87c26820d903bb8aad81754f"/>
<!-- Information: platform/external/bluetooth/bluez is tagged with M76XXUSNEKNLYA2040 --><project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="1023c91c66e9c3bd1132480051993bf7827770f6"/>
<!-- Information: platform/external/bluetooth/glib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="c6b49241cc1a8950723a5f74f8f4b4f4c3fa970e"/>
<!-- Information: platform/external/bluetooth/glib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="c6b49241cc1a8950723a5f74f8f4b4f4c3fa970e"/>
<!-- Information: platform/external/bluetooth/hcidump is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/bluetooth/hcidump" path="external/bluetooth/hcidump" revision="02b1eb24fbb3d0135a81edb4a2175b1397308d7d"/>
<!-- Information: platform/external/bsdiff is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
<!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
<!-- Information: platform/external/bsdiff is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
<!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
<!-- Information: platform/external/dbus is tagged with M8960AAAAANLYA100715A --><project name="platform/external/dbus" path="external/dbus" revision="c7517b6195dc6926728352113e6cc335da3f9c9e"/>
<!-- Information: platform/external/dhcpcd is tagged with M8960AAAAANLYA100715A --><project name="platform/external/dhcpcd" path="external/dhcpcd" revision="1e00fb67022d0921af0fead263f81762781b9ffa"/>
<!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
<!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="d5f550bb2f556c5d287f7c8d2b77223654bcec37"/>
<!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
<!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
<!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
<!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
<!-- Information: platform/external/giflib is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
<!-- Information: platform/external/gtest is tagged with android-4.2.1_r1 --><project name="platform/external/gtest" path="external/gtest" remote="linaro" revision="344e5f3db17615cc853073a02968a603efd39109"/>
<!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="116610d63a859521dacf00fb6818ee9ab2e666f6"/>
<!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
<!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
<!-- Information: platform/external/jhead is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/jhead" path="external/jhead" revision="754078052c687f6721536009c816644c73e4f145"/>
<!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
<!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="d5f550bb2f556c5d287f7c8d2b77223654bcec37"/>
<!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
<!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
<!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
<!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
<!-- Information: platform/external/giflib is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
<!-- Information: platform/external/gtest is tagged with android-sdk-support_r11 --><project name="platform/external/gtest" path="external/gtest" remote="linaro" revision="344e5f3db17615cc853073a02968a603efd39109"/>
<!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="116610d63a859521dacf00fb6818ee9ab2e666f6"/>
<!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
<!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
<!-- Information: platform/external/jhead is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/jhead" path="external/jhead" revision="754078052c687f6721536009c816644c73e4f145"/>
<!-- Information: platform/external/jpeg is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/jpeg" path="external/jpeg" revision="a62e464d672a4623233180e4023034bf825f066e"/>
<!-- Information: platform/external/libgsm is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
<!-- Information: platform/external/liblzf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
<!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
<!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
<!-- Information: platform/external/libphonenumber is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/libphonenumber" path="external/libphonenumber" revision="8d22c9a05eda1935c6dc27d188158e6ee38dc016"/>
<!-- Information: platform/external/libgsm is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
<!-- Information: platform/external/liblzf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
<!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
<!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
<!-- Information: platform/external/libphonenumber is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/libphonenumber" path="external/libphonenumber" revision="8d22c9a05eda1935c6dc27d188158e6ee38dc016"/>
<!-- Information: platform/external/libpng is tagged with M8960AAAAANLYA100715A --><project name="platform/external/libpng" path="external/libpng" revision="9c3730f0efa69f580f03463c237cd928f3196404"/>
<!-- Information: platform/external/libvpx is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/libvpx" path="external/libvpx" revision="3a40da0d96da5c520e7707aa14f48a80956e20d7"/>
<!-- Information: platform/external/libvpx is tagged with M8960AAAAANLYA1519349 --><project name="platform/external/libvpx" path="external/libvpx" revision="3a40da0d96da5c520e7707aa14f48a80956e20d7"/>
<!-- Information: platform/external/llvm is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/llvm" path="external/llvm" revision="bff5923831940309f7d8ddbff5826ca6ed2dc050"/>
<!-- Information: platform/external/mksh is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/mksh" path="external/mksh" revision="ec646e8f5e7dac9a77d1de549c6ed92c04d0cd4b"/>
<project name="platform_external_opensans" path="external/opensans" remote="b2g" revision="b5b4c226ca1d71e936153cf679dda6d3d60e2354"/>
<!-- Information: platform/external/openssl is tagged with AU_LINUX_ANDROID_ICS.04.00.04.00.110 --><project name="platform/external/openssl" path="external/openssl" revision="27d333cce9a31c806b4bfa042925f045c727aecd"/>
<!-- Information: platform/external/protobuf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
<!-- Information: platform/external/safe-iop is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
<!-- Information: platform/external/protobuf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
<!-- Information: platform/external/safe-iop is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
<project name="screencap-gonk" path="external/screencap-gonk" remote="b2g" revision="e6403c71e9eca8cb943739d5a0a192deac60fc51"/>
<!-- Information: platform/external/skia is tagged with M8960AAAAANLYA100715A --><project name="platform/external/skia" path="external/skia" revision="7d90c85f2c0e3b747f7c7eff8bc9253b0063b439"/>
<!-- Information: platform/external/sonivox is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/sonivox" path="external/sonivox" revision="7c967779dfc61ac1f346e972de91d4bfce7dccbb"/>
<!-- Information: platform/external/speex is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
<!-- Information: platform/external/speex is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
<project name="platform/external/sqlite" path="external/sqlite" revision="fb30e613139b8836fdc8e81e166cf3a76e5fa17f"/>
<!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
<!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
<!-- Information: platform/external/tagsoup is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
<!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
<!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
<!-- Information: platform/external/tagsoup is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
<!-- Information: platform/external/tinyalsa is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/tinyalsa" path="external/tinyalsa" revision="06cc244ee512c1352215e543615738bc8ac82814"/>
<!-- Information: platform/external/tremolo is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
<!-- Information: platform/external/tremolo is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
<project name="unbootimg" path="external/unbootimg" remote="b2g" revision="9464623d92eb8668544916dc5a8f4f6337d0bc08"/>
<!-- Information: platform/external/webp is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
<!-- Information: platform/external/webrtc is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/webrtc" path="external/webrtc" revision="137024dc8a2e9251a471e20518a9c3ae06f81f23"/>
<!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
<!-- Information: platform/external/webp is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
<!-- Information: platform/external/webrtc is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/webrtc" path="external/webrtc" revision="137024dc8a2e9251a471e20518a9c3ae06f81f23"/>
<!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
<!-- Information: platform/external/hostap is tagged with M8960AAAAANLYA1047 --><project name="platform/external/hostap" path="external/hostap" revision="bf04b0faadbdeb4b7943f2e2c4c5aa59df872bb1"/>
<!-- Information: platform/external/zlib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/zlib" path="external/zlib" revision="f96a1d1ebfdf1cd582210fd09c23d8f59e0ae094"/>
<!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
<!-- Information: platform/external/zlib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/zlib" path="external/zlib" revision="f96a1d1ebfdf1cd582210fd09c23d8f59e0ae094"/>
<!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
<!-- Information: platform/frameworks/base is tagged with M76XXUSNEKNLYA2040 --><project name="platform/frameworks/base" path="frameworks/base" revision="eb2bc75803ca179353c24c364a9c8a8ce23e8b78"/>
<!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
<!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
<!-- Information: platform/frameworks/support is tagged with M8960AAAAANLYA1005304 --><project name="platform/frameworks/support" path="frameworks/support" revision="27208692b001981f1806f4f396434f4eac78b909"/>
<!-- Information: platform/hardware/libhardware is tagged with M8960AAAAANLYA1049B --><project name="platform/hardware/libhardware" path="hardware/libhardware" revision="4a619901847621f8a7305edf42dd07347a140484"/>
<!-- Information: platform/hardware/libhardware_legacy is tagged with M8960AAAAANLYA153611 --><project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="87b4d7afa8f854b445e2d0d95091f6f6069f2b30"/>
<!-- Information: platform/libcore is tagged with M8960AAAAANLYA100715A --><project name="platform/libcore" path="libcore" revision="30841f9fba9ccd5c54f4f079f495994db97f283e"/>
<!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
<!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
<!-- Information: platform/prebuilt is tagged with M8960AAAAANLYA1005304 --><project name="platform/prebuilt" path="prebuilt" revision="447ea790fcc957dde59730ecc2a65ca263bdc733"/>
<!-- Information: platform/system/bluetooth is tagged with M8960AAAAANLYA100703 --><project name="platform/system/bluetooth" path="system/bluetooth" revision="7772cad4823f1f427ce1d4df84a55982386d6d18"/>
<!-- Information: platform/system/core is tagged with M76XXUSNEKNLYA2040 --><project name="platform/system/core" path="system/core" revision="bf1970408676ce570b8f4dc3efa038e47552137f"/>
@ -96,14 +96,14 @@
<!-- Otoro/Unagi specific things -->
<!-- Information: device/qcom/common is tagged with M8960AAAAANLYA100715A --><project name="device/qcom/common" path="device/qcom/common" revision="b9cdab8e1e1a215a8c65b8d5816f666bec7be205"/>
<!-- Information: platform/vendor/qcom/msm7627a is tagged with M8960AAAAANLYA100715A --><project name="platform/vendor/qcom/msm7627a" path="device/qcom/msm7627a" revision="d920a502ba17cf4d716f8b1a615f07e796b0501a"/>
<project name="android-device-otoro" path="device/qcom/otoro" remote="b2g" revision="e3e99b264dd0230108aa78f2b653db4ce0e494fb"/>
<project name="android-device-unagi" path="device/qcom/unagi" remote="b2g" revision="e74925a10e11a4f0bc56158c248bd20c521d3dd7"/>
<project name="android-device-otoro" path="device/qcom/otoro" remote="b2g" revision="7662275433fc0b1d8b035f03185b24b7ca965ab4"/>
<project name="android-device-unagi" path="device/qcom/unagi" remote="b2g" revision="6c014552d1b26bee611d9a9b23bd4cd014e392ee"/>
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="0a01247e4b0880f93424b27251cd3a1f6b19dbb2"/>
<!-- Information: platform/hardware/qcom/camera is tagged with M76XXUSNEKNLYA2040 --><project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="1acf77a75e30f3fc8b1eed2057c97adf1cb1633f"/>
<project name="hardware_qcom_display" path="hardware/qcom/display" remote="b2g" revision="6405d30f2fac7d8a1f2cb17b99fb7dd0a8bcfdac"/>
<!-- Information: platform/hardware/qcom/media is tagged with M8960AAAAANLYA100715A --><project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="552c3ddb7174a01f3508782d40c4d8c845ab441a"/>
<!-- Information: platform/hardware/qcom/gps is tagged with M8960AAAAANLYA100705 --><project name="platform/hardware/qcom/gps" path="hardware/qcom/gps" revision="23d5707b320d7fc69f8ba3b7d84d78a1c5681708"/>
<!-- Information: platform/hardware/msm7k is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/hardware/msm7k" path="hardware/msm7k" revision="8892d46805c5639b55dd07547745c5180da861e7"/>
<!-- Information: platform/hardware/msm7k is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/hardware/msm7k" path="hardware/msm7k" revision="8892d46805c5639b55dd07547745c5180da861e7"/>
<!-- Information: platform/vendor/qcom-opensource/omx/mm-core is tagged with M8960AAAAANLYA100715A --><project name="platform/vendor/qcom-opensource/omx/mm-core" path="vendor/qcom/opensource/omx/mm-core" revision="ab17ac9a074b4bb69986a8436336bdfbbaf9cd39"/>
<!-- Information: platform/hardware/ril is tagged with M76XXUSNEKNLYA1610 --><project name="platform/hardware/ril" path="hardware/ril" remote="caf" revision="fe9a3f63922143b57e79ed570bab2328df8c83a5"/>
</manifest>

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1358464191000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1358893928000">
<emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*">
@ -214,6 +214,10 @@
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i256" id="/^[0-9a-f]+@[0-9a-f]+\.info/">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i22" id="ShopperReports@ShopperReports.com">
<versionRange minVersion="3.1.22.0" maxVersion="3.1.22.0">
</versionRange>
@ -226,7 +230,7 @@
</emItem>
<emItem blockID="i48" id="admin@youtubespeedup.com">
</emItem>
<emItem blockID="i109" id="{392e123b-b691-4a5e-b52f-c4c1027e749c}">
<emItem blockID="i104" id="yasd@youasdr3.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
@ -290,7 +294,7 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i104" id="yasd@youasdr3.com">
<emItem blockID="i109" id="{392e123b-b691-4a5e-b52f-c4c1027e749c}">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>

Просмотреть файл

@ -655,6 +655,9 @@ var gPluginHandler = {
}];
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
let dismissed = notification ? notification.dismissed : true;
// Always show the doorhanger if the anchor is not available.
if (!isElementVisible(gURLBar))
dismissed = false;
let options = { dismissed: dismissed, centerActions: centerActions };
let icon = haveVulnerablePlugin ? "blocked-plugins-notification-icon" : "plugins-notification-icon"
PopupNotifications.show(aBrowser, "click-to-play-plugins",

Просмотреть файл

@ -274,6 +274,8 @@
side="right"
type="arrow"
hidden="true"
rolluponmousewheel="true"
consumeoutsideclicks="false"
noautofocus="true"
position="topcenter topright"/>

Просмотреть файл

@ -11,9 +11,13 @@ function test() {
gURLBar.removeEventListener("focus", onFocus);
ok(true, "Invoked onfocus handler");
EventUtils.synthesizeKey("VK_RETURN", { shiftKey: true });
ok(true, "Evaluated without crashing");
finish();
// javscript: URIs are evaluated async.
SimpleTest.executeSoon(function() {
ok(true, "Evaluated without crashing");
finish();
});
});
gURLBar.inputField.value = "javascript: document.body.innerHTML = '11111111'); ";
gURLBar.inputField.value = "javascript: var foo = '11111111'; ";
gURLBar.focus();
}

Просмотреть файл

@ -54,30 +54,36 @@ var gAllTests = [
function () {
// Add history (within the past hour)
let uris = [];
let places = [];
let pURI;
for (let i = 0; i < 30; i++) {
uris.push(addHistoryWithMinutesAgo(i));
pURI = makeURI("http://" + i + "-minutes-ago.com/");
places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)});
uris.push(pURI);
}
let wh = new WindowHelper();
wh.onload = function () {
this.selectDuration(Sanitizer.TIMESPAN_HOUR);
this.checkPrefCheckbox("history", false);
this.checkDetails(false);
addVisits(places, function() {
let wh = new WindowHelper();
wh.onload = function () {
this.selectDuration(Sanitizer.TIMESPAN_HOUR);
this.checkPrefCheckbox("history", false);
this.checkDetails(false);
// Show details
this.toggleDetails();
this.checkDetails(true);
// Show details
this.toggleDetails();
this.checkDetails(true);
// Hide details
this.toggleDetails();
this.checkDetails(false);
this.cancelDialog();
// Hide details
this.toggleDetails();
this.checkDetails(false);
this.cancelDialog();
ensureHistoryClearedState(uris, false);
blankSlate();
ensureHistoryClearedState(uris, true);
};
wh.open();
ensureHistoryClearedState(uris, false);
blankSlate();
ensureHistoryClearedState(uris, true);
};
wh.open();
});
},
/**
@ -85,56 +91,67 @@ var gAllTests = [
* visits and downloads when checked; the dialog respects simple timespan.
*/
function () {
// Add history and downloads (within the past hour).
// Add history (within the past hour).
let uris = [];
let places = [];
let pURI;
for (let i = 0; i < 30; i++) {
uris.push(addHistoryWithMinutesAgo(i));
pURI = makeURI("http://" + i + "-minutes-ago.com/");
places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)});
uris.push(pURI);
}
let downloadIDs = [];
for (let i = 0; i < 5; i++) {
downloadIDs.push(addDownloadWithMinutesAgo(i));
}
// Add history and downloads (over an hour ago).
// Add history (over an hour ago).
let olderURIs = [];
for (let i = 0; i < 5; i++) {
olderURIs.push(addHistoryWithMinutesAgo(61 + i));
pURI = makeURI("http://" + (61 + i) + "-minutes-ago.com/");
places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(61 + i)});
olderURIs.push(pURI);
}
let olderDownloadIDs = [];
for (let i = 0; i < 5; i++) {
olderDownloadIDs.push(addDownloadWithMinutesAgo(61 + i));
}
let totalHistoryVisits = uris.length + olderURIs.length;
let wh = new WindowHelper();
wh.onload = function () {
this.selectDuration(Sanitizer.TIMESPAN_HOUR);
this.checkPrefCheckbox("history", true);
this.acceptDialog();
addVisits(places, function() {
// Add downloads (within the past hour).
let downloadIDs = [];
for (let i = 0; i < 5; i++) {
downloadIDs.push(addDownloadWithMinutesAgo(i));
}
// Add downloads (over an hour ago).
let olderDownloadIDs = [];
for (let i = 0; i < 5; i++) {
olderDownloadIDs.push(addDownloadWithMinutesAgo(61 + i));
}
let totalHistoryVisits = uris.length + olderURIs.length;
intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_HOUR,
"timeSpan pref should be hour after accepting dialog with " +
"hour selected");
boolPrefIs("cpd.history", true,
"history pref should be true after accepting dialog with " +
"history checkbox checked");
boolPrefIs("cpd.downloads", true,
"downloads pref should be true after accepting dialog with " +
"history checkbox checked");
let wh = new WindowHelper();
wh.onload = function () {
this.selectDuration(Sanitizer.TIMESPAN_HOUR);
this.checkPrefCheckbox("history", true);
this.acceptDialog();
// History visits and downloads within one hour should be cleared.
ensureHistoryClearedState(uris, true);
ensureDownloadsClearedState(downloadIDs, true);
intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_HOUR,
"timeSpan pref should be hour after accepting dialog with " +
"hour selected");
boolPrefIs("cpd.history", true,
"history pref should be true after accepting dialog with " +
"history checkbox checked");
boolPrefIs("cpd.downloads", true,
"downloads pref should be true after accepting dialog with " +
"history checkbox checked");
// Visits and downloads > 1 hour should still exist.
ensureHistoryClearedState(olderURIs, false);
ensureDownloadsClearedState(olderDownloadIDs, false);
// History visits and downloads within one hour should be cleared.
ensureHistoryClearedState(uris, true);
ensureDownloadsClearedState(downloadIDs, true);
// OK, done, cleanup after ourselves.
blankSlate();
ensureHistoryClearedState(olderURIs, true);
ensureDownloadsClearedState(olderDownloadIDs, true);
};
wh.open();
// Visits and downloads > 1 hour should still exist.
ensureHistoryClearedState(olderURIs, false);
ensureDownloadsClearedState(olderDownloadIDs, false);
// OK, done, cleanup after ourselves.
blankSlate();
ensureHistoryClearedState(olderURIs, true);
ensureDownloadsClearedState(olderDownloadIDs, true);
};
wh.open();
});
},
/**
@ -144,51 +161,58 @@ var gAllTests = [
function () {
// Add history, downloads, form entries (within the past hour).
let uris = [];
let places = [];
let pURI;
for (let i = 0; i < 5; i++) {
uris.push(addHistoryWithMinutesAgo(i));
}
let downloadIDs = [];
for (let i = 0; i < 5; i++) {
downloadIDs.push(addDownloadWithMinutesAgo(i));
}
let formEntries = [];
for (let i = 0; i < 5; i++) {
formEntries.push(addFormEntryWithMinutesAgo(i));
pURI = makeURI("http://" + i + "-minutes-ago.com/");
places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)});
uris.push(pURI);
}
let wh = new WindowHelper();
wh.onload = function () {
is(this.isWarningPanelVisible(), false,
"Warning panel should be hidden after previously accepting dialog " +
"with a predefined timespan");
this.selectDuration(Sanitizer.TIMESPAN_HOUR);
addVisits(places, function() {
let downloadIDs = [];
for (let i = 0; i < 5; i++) {
downloadIDs.push(addDownloadWithMinutesAgo(i));
}
let formEntries = [];
for (let i = 0; i < 5; i++) {
formEntries.push(addFormEntryWithMinutesAgo(i));
}
// Remove only form entries, leave history (including downloads).
this.checkPrefCheckbox("history", false);
this.checkPrefCheckbox("formdata", true);
this.acceptDialog();
let wh = new WindowHelper();
wh.onload = function () {
is(this.isWarningPanelVisible(), false,
"Warning panel should be hidden after previously accepting dialog " +
"with a predefined timespan");
this.selectDuration(Sanitizer.TIMESPAN_HOUR);
intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_HOUR,
"timeSpan pref should be hour after accepting dialog with " +
"hour selected");
boolPrefIs("cpd.history", false,
"history pref should be false after accepting dialog with " +
"history checkbox unchecked");
boolPrefIs("cpd.downloads", false,
"downloads pref should be false after accepting dialog with " +
"history checkbox unchecked");
// Remove only form entries, leave history (including downloads).
this.checkPrefCheckbox("history", false);
this.checkPrefCheckbox("formdata", true);
this.acceptDialog();
// Of the three only form entries should be cleared.
ensureHistoryClearedState(uris, false);
ensureDownloadsClearedState(downloadIDs, false);
ensureFormEntriesClearedState(formEntries, true);
intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_HOUR,
"timeSpan pref should be hour after accepting dialog with " +
"hour selected");
boolPrefIs("cpd.history", false,
"history pref should be false after accepting dialog with " +
"history checkbox unchecked");
boolPrefIs("cpd.downloads", false,
"downloads pref should be false after accepting dialog with " +
"history checkbox unchecked");
// OK, done, cleanup after ourselves.
blankSlate();
ensureHistoryClearedState(uris, true);
ensureDownloadsClearedState(downloadIDs, true);
};
wh.open();
// Of the three only form entries should be cleared.
ensureHistoryClearedState(uris, false);
ensureDownloadsClearedState(downloadIDs, false);
ensureFormEntriesClearedState(formEntries, true);
// OK, done, cleanup after ourselves.
blankSlate();
ensureHistoryClearedState(uris, true);
ensureDownloadsClearedState(downloadIDs, true);
};
wh.open();
});
},
/**
@ -197,36 +221,42 @@ var gAllTests = [
function () {
// Add history.
let uris = [];
uris.push(addHistoryWithMinutesAgo(10)); // within past hour
uris.push(addHistoryWithMinutesAgo(70)); // within past two hours
uris.push(addHistoryWithMinutesAgo(130)); // within past four hours
uris.push(addHistoryWithMinutesAgo(250)); // outside past four hours
let places = [];
let pURI;
// within past hour, within past two hours, within past four hours and
// outside past four hours
[10, 70, 130, 250].forEach(function(aValue) {
pURI = makeURI("http://" + aValue + "-minutes-ago.com/");
places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(aValue)});
uris.push(pURI);
});
addVisits(places, function() {
let wh = new WindowHelper();
wh.onload = function () {
is(this.isWarningPanelVisible(), false,
"Warning panel should be hidden after previously accepting dialog " +
"with a predefined timespan");
this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
this.checkPrefCheckbox("history", true);
this.checkDetails(true);
let wh = new WindowHelper();
wh.onload = function () {
is(this.isWarningPanelVisible(), false,
"Warning panel should be hidden after previously accepting dialog " +
"with a predefined timespan");
this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
this.checkPrefCheckbox("history", true);
this.checkDetails(true);
// Hide details
this.toggleDetails();
this.checkDetails(false);
// Hide details
this.toggleDetails();
this.checkDetails(false);
// Show details
this.toggleDetails();
this.checkDetails(true);
// Show details
this.toggleDetails();
this.checkDetails(true);
this.acceptDialog();
this.acceptDialog();
intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_EVERYTHING,
"timeSpan pref should be everything after accepting dialog " +
"with everything selected");
ensureHistoryClearedState(uris, true);
};
wh.open();
intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_EVERYTHING,
"timeSpan pref should be everything after accepting dialog " +
"with everything selected");
ensureHistoryClearedState(uris, true);
};
wh.open();
});
},
/**
@ -236,26 +266,32 @@ var gAllTests = [
function () {
// Add history.
let uris = [];
uris.push(addHistoryWithMinutesAgo(10)); // within past hour
uris.push(addHistoryWithMinutesAgo(70)); // within past two hours
uris.push(addHistoryWithMinutesAgo(130)); // within past four hours
uris.push(addHistoryWithMinutesAgo(250)); // outside past four hours
let places = [];
let pURI;
// within past hour, within past two hours, within past four hours and
// outside past four hours
[10, 70, 130, 250].forEach(function(aValue) {
pURI = makeURI("http://" + aValue + "-minutes-ago.com/");
places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(aValue)});
uris.push(pURI);
});
addVisits(places, function() {
let wh = new WindowHelper();
wh.onload = function () {
is(this.isWarningPanelVisible(), true,
"Warning panel should be visible after previously accepting dialog " +
"with clearing everything");
this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
this.checkPrefCheckbox("history", true);
this.acceptDialog();
let wh = new WindowHelper();
wh.onload = function () {
is(this.isWarningPanelVisible(), true,
"Warning panel should be visible after previously accepting dialog " +
"with clearing everything");
this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
this.checkPrefCheckbox("history", true);
this.acceptDialog();
intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_EVERYTHING,
"timeSpan pref should be everything after accepting dialog " +
"with everything selected");
ensureHistoryClearedState(uris, true);
};
wh.open();
intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_EVERYTHING,
"timeSpan pref should be everything after accepting dialog " +
"with everything selected");
ensureHistoryClearedState(uris, true);
};
wh.open();
});
},
/**
@ -265,29 +301,32 @@ var gAllTests = [
*/
function () {
// Add history.
let uris = [ addHistoryWithMinutesAgo(10) ];
let formEntries = [ addFormEntryWithMinutesAgo(10) ];
let pURI = makeURI("http://" + 10 + "-minutes-ago.com/");
addVisits({uri: pURI, visitDate: visitTimeForMinutesAgo(10)}, function() {
let uris = [ pURI ];
let formEntries = [ addFormEntryWithMinutesAgo(10) ];
let wh = new WindowHelper();
wh.onload = function() {
// Check that the relevant checkboxes are enabled
var cb = this.win.document.querySelectorAll(
"#itemList > [preference='privacy.cpd.formdata']");
ok(cb.length == 1 && !cb[0].disabled, "There is formdata, checkbox to " +
"clear formdata should be enabled.");
let wh = new WindowHelper();
wh.onload = function() {
// Check that the relevant checkboxes are enabled
var cb = this.win.document.querySelectorAll(
"#itemList > [preference='privacy.cpd.formdata']");
ok(cb.length == 1 && !cb[0].disabled, "There is formdata, checkbox to " +
"clear formdata should be enabled.");
var cb = this.win.document.querySelectorAll(
"#itemList > [preference='privacy.cpd.history']");
ok(cb.length == 1 && !cb[0].disabled, "There is history, checkbox to " +
"clear history should be enabled.");
var cb = this.win.document.querySelectorAll(
"#itemList > [preference='privacy.cpd.history']");
ok(cb.length == 1 && !cb[0].disabled, "There is history, checkbox to " +
"clear history should be enabled.");
this.checkAllCheckboxes();
this.acceptDialog();
this.checkAllCheckboxes();
this.acceptDialog();
ensureHistoryClearedState(uris, true);
ensureFormEntriesClearedState(formEntries, true);
};
wh.open();
ensureHistoryClearedState(uris, true);
ensureFormEntriesClearedState(formEntries, true);
};
wh.open();
});
},
function () {
let wh = new WindowHelper();
@ -853,26 +892,6 @@ function addFormEntryWithMinutesAgo(aMinutesAgo) {
return name;
}
/**
* Adds a history visit to history.
*
* @param aMinutesAgo
* The visit will be visited this many minutes ago
*/
function addHistoryWithMinutesAgo(aMinutesAgo) {
let pURI = makeURI("http://" + aMinutesAgo + "-minutes-ago.com/");
PlacesUtils.history.addVisit(pURI,
now_uSec - aMinutesAgo * kUsecPerMin,
null,
Ci.nsINavHistoryService.TRANSITION_LINK,
false,
0);
is(PlacesUtils.bhistory.isVisited(pURI), true,
"Sanity check: history visit " + pURI.spec +
" should exist after creating it");
return pURI;
}
/**
* Removes all history visits, downloads, and form entries.
*/
@ -1034,6 +1053,16 @@ function intPrefIs(aPrefName, aExpectedVal, aMsg) {
is(gPrefService.getIntPref("privacy." + aPrefName), aExpectedVal, aMsg);
}
/**
* Creates a visit time.
*
* @param aMinutesAgo
* The visit will be visited this many minutes ago
*/
function visitTimeForMinutesAgo(aMinutesAgo) {
return now_uSec - aMinutesAgo * kUsecPerMin;
}
///////////////////////////////////////////////////////////////////////////////
function test() {

Просмотреть файл

@ -35,48 +35,54 @@ var gAllTests = [
function () {
// Add history (within the past hour) to get some rows in the tree.
let uris = [];
let places = [];
let pURI;
for (let i = 0; i < 30; i++) {
uris.push(addHistoryWithMinutesAgo(i));
pURI = makeURI("http://" + i + "-minutes-ago.com/");
places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)});
uris.push(pURI);
}
// Open the dialog and do our tests.
openWindow(function (aWin) {
let wh = new WindowHelper(aWin);
wh.selectDuration(Sanitizer.TIMESPAN_HOUR);
wh.checkGrippy("Grippy should be at last row after selecting HOUR " +
"duration",
wh.getRowCount() - 1);
addVisits(places, function() {
// Open the dialog and do our tests.
openWindow(function (aWin) {
let wh = new WindowHelper(aWin);
wh.selectDuration(Sanitizer.TIMESPAN_HOUR);
wh.checkGrippy("Grippy should be at last row after selecting HOUR " +
"duration",
wh.getRowCount() - 1);
// Move the grippy around.
let row = wh.getGrippyRow();
while (row !== 0) {
row--;
// Move the grippy around.
let row = wh.getGrippyRow();
while (row !== 0) {
row--;
wh.moveGrippyBy(-1);
wh.checkGrippy("Grippy should be moved up one row", row);
}
wh.moveGrippyBy(-1);
wh.checkGrippy("Grippy should be moved up one row", row);
}
wh.moveGrippyBy(-1);
wh.checkGrippy("Grippy should remain at first row after trying to move " +
"it up",
0);
while (row !== wh.getRowCount() - 1) {
row++;
wh.checkGrippy("Grippy should remain at first row after trying to move " +
"it up",
0);
while (row !== wh.getRowCount() - 1) {
row++;
wh.moveGrippyBy(1);
wh.checkGrippy("Grippy should be moved down one row", row);
}
wh.moveGrippyBy(1);
wh.checkGrippy("Grippy should be moved down one row", row);
}
wh.moveGrippyBy(1);
wh.checkGrippy("Grippy should remain at last row after trying to move " +
"it down",
wh.getRowCount() - 1);
wh.checkGrippy("Grippy should remain at last row after trying to move " +
"it down",
wh.getRowCount() - 1);
// Cancel the dialog, make sure history visits are not cleared.
wh.checkPrefCheckbox("history", false);
// Cancel the dialog, make sure history visits are not cleared.
wh.checkPrefCheckbox("history", false);
wh.cancelDialog();
ensureHistoryClearedState(uris, false);
wh.cancelDialog();
ensureHistoryClearedState(uris, false);
// OK, done, cleanup after ourselves.
blankSlate();
ensureHistoryClearedState(uris, true);
// OK, done, cleanup after ourselves.
blankSlate();
ensureHistoryClearedState(uris, true);
});
});
},
@ -85,49 +91,60 @@ var gAllTests = [
* visits and downloads when checked; the dialog respects simple timespan.
*/
function () {
// Add history and downloads (within the past hour).
// Add history (within the past hour).
let uris = [];
let places = [];
let pURI;
for (let i = 0; i < 30; i++) {
uris.push(addHistoryWithMinutesAgo(i));
pURI = makeURI("http://" + i + "-minutes-ago.com/");
places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)});
uris.push(pURI);
}
let downloadIDs = [];
for (let i = 0; i < 5; i++) {
downloadIDs.push(addDownloadWithMinutesAgo(i));
}
// Add history and downloads (over an hour ago).
// Add history (over an hour ago).
let olderURIs = [];
for (let i = 0; i < 5; i++) {
olderURIs.push(addHistoryWithMinutesAgo(61 + i));
pURI = makeURI("http://" + (60 + i) + "-minutes-ago.com/");
places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(60 + i)});
olderURIs.push(pURI);
}
let olderDownloadIDs = [];
for (let i = 0; i < 5; i++) {
olderDownloadIDs.push(addDownloadWithMinutesAgo(61 + i));
}
let totalHistoryVisits = uris.length + olderURIs.length;
// Open the dialog and do our tests.
openWindow(function (aWin) {
let wh = new WindowHelper(aWin);
wh.selectDuration(Sanitizer.TIMESPAN_HOUR);
wh.checkGrippy("Grippy should be at proper row after selecting HOUR " +
"duration",
uris.length);
addVisits(places, function() {
// Add downloads (within the past hour).
let downloadIDs = [];
for (let i = 0; i < 5; i++) {
downloadIDs.push(addDownloadWithMinutesAgo(i));
}
// Add downloads (over an hour ago).
let olderDownloadIDs = [];
for (let i = 0; i < 5; i++) {
olderDownloadIDs.push(addDownloadWithMinutesAgo(61 + i));
}
let totalHistoryVisits = uris.length + olderURIs.length;
// Accept the dialog, make sure history visits and downloads within one
// hour are cleared.
wh.checkPrefCheckbox("history", true);
wh.acceptDialog();
ensureHistoryClearedState(uris, true);
ensureDownloadsClearedState(downloadIDs, true);
// Open the dialog and do our tests.
openWindow(function (aWin) {
let wh = new WindowHelper(aWin);
wh.selectDuration(Sanitizer.TIMESPAN_HOUR);
wh.checkGrippy("Grippy should be at proper row after selecting HOUR " +
"duration",
uris.length);
// Make sure visits and downloads > 1 hour still exist.
ensureHistoryClearedState(olderURIs, false);
ensureDownloadsClearedState(olderDownloadIDs, false);
// Accept the dialog, make sure history visits and downloads within one
// hour are cleared.
wh.checkPrefCheckbox("history", true);
wh.acceptDialog();
ensureHistoryClearedState(uris, true);
ensureDownloadsClearedState(downloadIDs, true);
// OK, done, cleanup after ourselves.
blankSlate();
ensureHistoryClearedState(olderURIs, true);
ensureDownloadsClearedState(olderDownloadIDs, true);
// Make sure visits and downloads > 1 hour still exist.
ensureHistoryClearedState(olderURIs, false);
ensureDownloadsClearedState(olderDownloadIDs, false);
// OK, done, cleanup after ourselves.
blankSlate();
ensureHistoryClearedState(olderURIs, true);
ensureDownloadsClearedState(olderDownloadIDs, true);
});
});
},
@ -138,40 +155,47 @@ var gAllTests = [
function () {
// Add history, downloads, form entries (within the past hour).
let uris = [];
let places = [];
let pURI;
for (let i = 0; i < 5; i++) {
uris.push(addHistoryWithMinutesAgo(i));
}
let downloadIDs = [];
for (let i = 0; i < 5; i++) {
downloadIDs.push(addDownloadWithMinutesAgo(i));
}
let formEntries = [];
for (let i = 0; i < 5; i++) {
formEntries.push(addFormEntryWithMinutesAgo(i));
pURI = makeURI("http://" + i + "-minutes-ago.com/");
places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)});
uris.push(pURI);
}
// Open the dialog and do our tests.
openWindow(function (aWin) {
let wh = new WindowHelper(aWin);
wh.selectDuration(Sanitizer.TIMESPAN_HOUR);
wh.checkGrippy("Grippy should be at last row after selecting HOUR " +
"duration",
wh.getRowCount() - 1);
addVisits(places, function() {
let downloadIDs = [];
for (let i = 0; i < 5; i++) {
downloadIDs.push(addDownloadWithMinutesAgo(i));
}
let formEntries = [];
for (let i = 0; i < 5; i++) {
formEntries.push(addFormEntryWithMinutesAgo(i));
}
// Remove only form entries, leave history (including downloads).
wh.checkPrefCheckbox("history", false);
wh.checkPrefCheckbox("formdata", true);
wh.acceptDialog();
// Open the dialog and do our tests.
openWindow(function (aWin) {
let wh = new WindowHelper(aWin);
wh.selectDuration(Sanitizer.TIMESPAN_HOUR);
wh.checkGrippy("Grippy should be at last row after selecting HOUR " +
"duration",
wh.getRowCount() - 1);
// Of the three only form entries should be cleared.
ensureHistoryClearedState(uris, false);
ensureDownloadsClearedState(downloadIDs, false);
ensureFormEntriesClearedState(formEntries, true);
// Remove only form entries, leave history (including downloads).
wh.checkPrefCheckbox("history", false);
wh.checkPrefCheckbox("formdata", true);
wh.acceptDialog();
// OK, done, cleanup after ourselves.
blankSlate();
ensureHistoryClearedState(uris, true);
ensureDownloadsClearedState(downloadIDs, true);
// Of the three only form entries should be cleared.
ensureHistoryClearedState(uris, false);
ensureDownloadsClearedState(downloadIDs, false);
ensureFormEntriesClearedState(formEntries, true);
// OK, done, cleanup after ourselves.
blankSlate();
ensureHistoryClearedState(uris, true);
ensureDownloadsClearedState(downloadIDs, true);
});
});
},
@ -181,18 +205,25 @@ var gAllTests = [
function () {
// Add history.
let uris = [];
uris.push(addHistoryWithMinutesAgo(10)); // within past hour
uris.push(addHistoryWithMinutesAgo(70)); // within past two hours
uris.push(addHistoryWithMinutesAgo(130)); // within past four hours
uris.push(addHistoryWithMinutesAgo(250)); // outside past four hours
let places = [];
let pURI;
// within past hour, within past two hours, within past four hours and
// outside past four hours
[10, 70, 130, 250].forEach(function(aValue) {
pURI = makeURI("http://" + aValue + "-minutes-ago.com/");
places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(aValue)});
uris.push(pURI);
});
addVisits(places, function() {
// Open the dialog and do our tests.
openWindow(function (aWin) {
let wh = new WindowHelper(aWin);
wh.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
wh.checkPrefCheckbox("history", true);
wh.acceptDialog();
ensureHistoryClearedState(uris, true);
// Open the dialog and do our tests.
openWindow(function (aWin) {
let wh = new WindowHelper(aWin);
wh.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
wh.checkPrefCheckbox("history", true);
wh.acceptDialog();
ensureHistoryClearedState(uris, true);
});
});
}
];
@ -462,26 +493,6 @@ function addFormEntryWithMinutesAgo(aMinutesAgo) {
return name;
}
/**
* Adds a history visit to history.
*
* @param aMinutesAgo
* The visit will be visited this many minutes ago
*/
function addHistoryWithMinutesAgo(aMinutesAgo) {
let pURI = makeURI("http://" + aMinutesAgo + "-minutes-ago.com/");
PlacesUtils.history.addVisit(pURI,
now_uSec - (aMinutesAgo * 60 * 1000 * 1000),
null,
Ci.nsINavHistoryService.TRANSITION_LINK,
false,
0);
is(PlacesUtils.bhistory.isVisited(pURI), true,
"Sanity check: history visit " + pURI.spec +
" should exist after creating it");
return pURI;
}
/**
* Removes all history visits, downloads, and form entries.
*/
@ -653,6 +664,16 @@ function openWindow(aOnloadCallback) {
null);
}
/**
* Creates a visit time.
*
* @param aMinutesAgo
* The visit will be visited this many minutes ago
*/
function visitTimeForMinutesAgo(aMinutesAgo) {
return now_uSec - (aMinutesAgo * 60 * 1000000);
}
///////////////////////////////////////////////////////////////////////////////
function test() {

Просмотреть файл

@ -2,7 +2,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init();
MockFilePicker.init(window);
let tempScope = {};
Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);

Просмотреть файл

@ -2,7 +2,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init();
MockFilePicker.init(window);
let tempScope = {};
Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);

Просмотреть файл

@ -2,7 +2,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init();
MockFilePicker.init(window);
function checkDiskCacheFor(filename) {
let visitor = {

Просмотреть файл

@ -116,7 +116,7 @@ function test() {
});
});
MockFilePicker.init();
MockFilePicker.init(window);
// then test when on private mode
testOnWindow({private: true}, function(aWin) {
doTest(true, aWin, finish);

Просмотреть файл

@ -2,7 +2,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init();
MockFilePicker.init(window);
/**
* TestCase for bug 564387

Просмотреть файл

@ -131,3 +131,42 @@ function whenNewWindowLoaded(aOptions, aCallback) {
aCallback(win);
}, false);
}
function addVisits(aPlaceInfo, aCallback) {
let places = [];
if (aPlaceInfo instanceof Ci.nsIURI) {
places.push({ uri: aPlaceInfo });
} else if (Array.isArray(aPlaceInfo)) {
places = places.concat(aPlaceInfo);
} else {
places.push(aPlaceInfo);
}
// Create mozIVisitInfo for each entry.
let now = Date.now();
for (let i = 0; i < places.length; i++) {
if (!places[i].title) {
places[i].title = "test visit for " + places[i].uri.spec;
}
places[i].visits = [{
transitionType: places[i].transition === undefined ? Ci.nsINavHistoryService.TRANSITION_LINK
: places[i].transition,
visitDate: places[i].visitDate || (now++) * 1000,
referrerURI: places[i].referrer
}];
}
PlacesUtils.asyncHistory.updatePlaces(
places,
{
handleError: function AAV_handleError() {
throw("Unexpected error in adding visit.");
},
handleResult: function () {},
handleCompletion: function UP_handleCompletion() {
if (aCallback)
aCallback();
}
}
);
}

Просмотреть файл

@ -2,12 +2,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
function add_visit(aURI, aReferrer) {
return PlacesUtils.history.addVisit(aURI, Date.now() * 1000, aReferrer,
PlacesUtils.history.TRANSITION_TYPED,
false, 0);
}
function add_bookmark(aURI) {
return PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
aURI, PlacesUtils.bookmarks.DEFAULT_INDEX,
@ -38,13 +32,14 @@ function onLibraryReady() {
ContentTree = gLibrary.ContentTree;
ok(ContentTree, "ContentTree is in scope");
tests.makeHistVisit();
tests.makeTag();
tests.focusTag();
waitForClipboard(function(aData) !!aData,
tests.copyHistNode,
onClipboardReady,
PlacesUtils.TYPE_X_MOZ_PLACE);
tests.makeHistVisit(function() {
tests.makeTag();
tests.focusTag();
waitForClipboard(function(aData) !!aData,
tests.copyHistNode,
onClipboardReady,
PlacesUtils.TYPE_X_MOZ_PLACE);
});
}
function onClipboardReady() {
@ -67,13 +62,17 @@ function onClipboardReady() {
let tests = {
makeHistVisit: function() {
makeHistVisit: function(aCallback) {
// need to add a history object
let testURI1 = NetUtil.newURI(MOZURISPEC);
isnot(testURI1, null, "testURI is not null");
let visitId = add_visit(testURI1);
ok(visitId > 0, "A visit was added to the history");
ok(PlacesUtils.ghistory2.isVisited(testURI1), MOZURISPEC + " is a visited url.");
addVisits(
{uri: testURI1, transition: PlacesUtils.history.TRANSITION_TYPED},
window,
function() {
ok(PlacesUtils.ghistory2.isVisited(testURI1), MOZURISPEC + " is a visited url.");
aCallback();
});
},
makeTag: function() {

Просмотреть файл

@ -40,17 +40,6 @@ var win = wm.getMostRecentWindow("navigator:browser");
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
getService(Ci.nsIWindowWatcher);
function add_visit(aURI, aDate) {
var visitId = PlacesUtils.history
.addVisit(aURI,
aDate,
null, // no referrer
PlacesUtils.history.TRANSITION_TYPED,
false, // not redirect
0);
return visitId;
}
function add_bookmark(aURI) {
var bId = PlacesUtils.bookmarks
.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
@ -75,8 +64,9 @@ gTests.push({
historyView: SIDEBAR_HISTORY_BYLASTVISITED_VIEW, // See constants above, only for History sidebar.
window: null, // Will contain handle of dialog window
setup: function() {
setup: function(aCallback) {
// Setup everything needed for this test, runs before everything else.
aCallback();
},
selectNode: function(tree) {
@ -110,8 +100,9 @@ gTests.push({
itemType: null,
window: null,
setup: function() {
setup: function(aCallback) {
// Nothing to do.
aCallback();
},
selectNode: function(tree) {
@ -169,7 +160,7 @@ gTests.push({
_itemId: null,
_cleanShutdown: false,
setup: function() {
setup: function(aCallback) {
// Add a bookmark in unsorted bookmarks folder.
this._itemId = add_bookmark(PlacesUtils._uri(TEST_URL));
ok(this._itemId > 0, "Correctly added a bookmark");
@ -178,6 +169,7 @@ gTests.push({
["testTag"]);
var tags = PlacesUtils.tagging.getTagsForURI(PlacesUtils._uri(TEST_URL));
is(tags[0], "testTag", "Correctly added a tag");
aCallback();
},
selectNode: function(tree) {
@ -265,8 +257,9 @@ gTests.push({
window: null,
_itemId: null,
setup: function() {
setup: function(aCallback) {
// Nothing to do.
aCallback();
},
selectNode: function(tree) {
@ -323,7 +316,7 @@ gTests.push({
_itemId: null,
_cleanShutdown: false,
setup: function() {
setup: function(aCallback) {
// Add a bookmark in unsorted bookmarks folder.
this._itemId = add_bookmark(PlacesUtils._uri(TEST_URL));
ok(this._itemId > 0, "Correctly added a bookmark");
@ -332,6 +325,7 @@ gTests.push({
["testTag"]);
var tags = PlacesUtils.tagging.getTagsForURI(PlacesUtils._uri(TEST_URL));
is(tags[0], "testTag", "Correctly added a tag");
aCallback();
},
selectNode: function(tree) {
@ -419,12 +413,13 @@ gTests.push({
historyView: SIDEBAR_HISTORY_BYLASTVISITED_VIEW,
window: null,
setup: function() {
setup: function(aCallback) {
// Add a visit.
add_visit(PlacesUtils._uri(TEST_URL), Date.now() * 1000);
// Sanity check.
var gh = PlacesUtils.history.QueryInterface(Ci.nsIGlobalHistory2);
ok(gh.isVisited(PlacesUtils._uri(TEST_URL)), TEST_URL + " is a visited url.");
addVisits(
{uri: PlacesUtils._uri(TEST_URL),
transition: PlacesUtils.history.TRANSITION_TYPED},
window,
aCallback);
},
selectNode: function(tree) {
@ -511,8 +506,9 @@ function runNextTest() {
// Goto next tests.
gCurrentTest = gTests.shift();
info("Start of test: " + gCurrentTest.desc);
gCurrentTest.setup();
execute_test_in_sidebar();
gCurrentTest.setup(function() {
execute_test_in_sidebar();
});
}
else {
// Finished all tests.

Просмотреть файл

@ -11,11 +11,18 @@ function test() {
// Add a history entry.
let TEST_URIs = ["http://www.mozilla.org/test1", "http://www.mozilla.org/test2"];
ok(PlacesUtils, "checking PlacesUtils, running in chrome context?");
let history = PlacesUtils.history;
let places = [];
TEST_URIs.forEach(function(TEST_URI) {
let visitId = history.addVisit(PlacesUtils._uri(TEST_URI), Date.now() * 1000,
null, PlacesUtils.history.TRANSITION_TYPED, false, 0);
ok(visitId > 0, TEST_URI + " successfully marked visited");
places.push({uri: PlacesUtils._uri(TEST_URI),
transition: PlacesUtils.history.TRANSITION_TYPED});
});
addVisits(places, window, function() {
testForgetThisSiteVisibility(1, function() {
testForgetThisSiteVisibility(2, function() {
// Cleanup
waitForClearHistory(finish);
});
});
});
function testForgetThisSiteVisibility(selectionCount, funcNext) {
@ -62,11 +69,5 @@ function test() {
EventUtils.synthesizeMouse(tree.body, x.value + width.value / 2, y.value + height.value / 2, {type: "contextmenu"}, organizer);
});
}
testForgetThisSiteVisibility(1, function() {
testForgetThisSiteVisibility(2, function() {
// Cleanup
waitForClearHistory(finish);
});
});
}

Просмотреть файл

@ -17,16 +17,6 @@ function uri(spec) {
var sidebar = document.getElementById("sidebar");
function add_visit(aURI, aDate) {
var visitId = hs.addVisit(aURI,
aDate,
null, // no referrer
hs.TRANSITION_TYPED, // user typed in URL bar
false, // not redirect
0);
return visitId;
}
// Visited pages listed by descending visit date.
var pages = [
"http://sidebar.mozilla.org/a",
@ -47,9 +37,15 @@ function test() {
function continue_test() {
// Add some visited page.
var time = Date.now();
for (var i = 0; i < pages.length; i++) {
add_visit(uri(pages[i]), (time - i) * 1000);
var pagesLength = pages.length;
var places = [];
for (var i = 0; i < pagesLength; i++) {
places.push({uri: uri(pages[i]), visitDate: (time - i) * 1000,
transition: hs.TRANSITION_TYPED});
}
addVisits(places, window, function() {
toggleSidebar("viewHistorySidebar", true);
});
sidebar.addEventListener("load", function() {
sidebar.removeEventListener("load", arguments.callee, true);
@ -71,7 +67,6 @@ function continue_test() {
waitForClearHistory(finish);
});
}, true);
toggleSidebar("viewHistorySidebar", true);
}
function check_sidebar_tree_order(aExpectedRows) {

Просмотреть файл

@ -21,101 +21,105 @@ gTests.push({
let ContentTree = gLibrary.ContentTree;
var infoBoxExpanderWrapper = getAndCheckElmtById("infoBoxExpanderWrapper");
function addVisitsCallback() {
var bhist = PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory);
ok(bhist.isVisited(PlacesUtils._uri(TEST_URI)), "Visit has been added.");
// open all bookmarks node
PO.selectLeftPaneQuery("AllBookmarks");
isnot(PO._places.selectedNode, null,
"Correctly selected all bookmarks node.");
checkInfoBoxSelected(PO);
ok(infoBoxExpanderWrapper.hidden,
"Expander button is hidden for all bookmarks node.");
checkAddInfoFieldsCollapsed(PO);
// open history node
PO.selectLeftPaneQuery("History");
isnot(PO._places.selectedNode, null, "Correctly selected history node.");
checkInfoBoxSelected(PO);
ok(infoBoxExpanderWrapper.hidden,
"Expander button is hidden for history node.");
checkAddInfoFieldsCollapsed(PO);
// open history child node
var historyNode = PO._places.selectedNode.
QueryInterface(Ci.nsINavHistoryContainerResultNode);
historyNode.containerOpen = true;
var childNode = historyNode.getChild(0);
isnot(childNode, null, "History node first child is not null.");
PO._places.selectNode(childNode);
checkInfoBoxSelected(PO);
ok(infoBoxExpanderWrapper.hidden,
"Expander button is hidden for history child node.");
checkAddInfoFieldsCollapsed(PO);
// open history item
var view = ContentTree.view.treeBoxObject.view;
ok(view.rowCount > 0, "History item exists.");
view.selection.select(0);
ok(infoBoxExpanderWrapper.hidden,
"Expander button is hidden for history item.");
checkAddInfoFieldsCollapsed(PO);
historyNode.containerOpen = false;
// open bookmarks menu node
PO.selectLeftPaneQuery("BookmarksMenu");
isnot(PO._places.selectedNode, null,
"Correctly selected bookmarks menu node.");
checkInfoBoxSelected(PO);
ok(infoBoxExpanderWrapper.hidden,
"Expander button is hidden for bookmarks menu node.");
checkAddInfoFieldsCollapsed(PO);
// open recently bookmarked node
var menuNode = PO._places.selectedNode.
QueryInterface(Ci.nsINavHistoryContainerResultNode);
menuNode.containerOpen = true;
childNode = menuNode.getChild(0);
isnot(childNode, null, "Bookmarks menu child node exists.");
var recentlyBookmarkedTitle = PlacesUIUtils.
getString("recentlyBookmarkedTitle");
isnot(recentlyBookmarkedTitle, null,
"Correctly got the recently bookmarked title locale string.");
is(childNode.title, recentlyBookmarkedTitle,
"Correctly selected recently bookmarked node.");
PO._places.selectNode(childNode);
checkInfoBoxSelected(PO);
ok(!infoBoxExpanderWrapper.hidden,
"Expander button is not hidden for recently bookmarked node.");
checkAddInfoFieldsNotCollapsed(PO);
// open first bookmark
var view = ContentTree.view.treeBoxObject.view;
ok(view.rowCount > 0, "Bookmark item exists.");
view.selection.select(0);
checkInfoBoxSelected(PO);
ok(!infoBoxExpanderWrapper.hidden,
"Expander button is not hidden for bookmark item.");
checkAddInfoFieldsNotCollapsed(PO);
checkAddInfoFields(PO, "bookmark item");
// make sure additional fields are still hidden in second bookmark item
ok(view.rowCount > 1, "Second bookmark item exists.");
view.selection.select(1);
checkInfoBoxSelected(PO);
ok(!infoBoxExpanderWrapper.hidden,
"Expander button is not hidden for second bookmark item.");
checkAddInfoFieldsNotCollapsed(PO);
checkAddInfoFields(PO, "second bookmark item");
menuNode.containerOpen = false;
waitForClearHistory(nextTest);
}
// add a visit to browser history
var bhist = PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory);
PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_URI), Date.now() * 1000,
null, PlacesUtils.history.TRANSITION_TYPED,
false, 0);
ok(bhist.isVisited(PlacesUtils._uri(TEST_URI)), "Visit has been added.");
// open all bookmarks node
PO.selectLeftPaneQuery("AllBookmarks");
isnot(PO._places.selectedNode, null,
"Correctly selected all bookmarks node.");
checkInfoBoxSelected(PO);
ok(infoBoxExpanderWrapper.hidden,
"Expander button is hidden for all bookmarks node.");
checkAddInfoFieldsCollapsed(PO);
// open history node
PO.selectLeftPaneQuery("History");
isnot(PO._places.selectedNode, null, "Correctly selected history node.");
checkInfoBoxSelected(PO);
ok(infoBoxExpanderWrapper.hidden,
"Expander button is hidden for history node.");
checkAddInfoFieldsCollapsed(PO);
// open history child node
var historyNode = PO._places.selectedNode.
QueryInterface(Ci.nsINavHistoryContainerResultNode);
historyNode.containerOpen = true;
var childNode = historyNode.getChild(0);
isnot(childNode, null, "History node first child is not null.");
PO._places.selectNode(childNode);
checkInfoBoxSelected(PO);
ok(infoBoxExpanderWrapper.hidden,
"Expander button is hidden for history child node.");
checkAddInfoFieldsCollapsed(PO);
// open history item
var view = ContentTree.view.treeBoxObject.view;
ok(view.rowCount > 0, "History item exists.");
view.selection.select(0);
ok(infoBoxExpanderWrapper.hidden,
"Expander button is hidden for history item.");
checkAddInfoFieldsCollapsed(PO);
historyNode.containerOpen = false;
// open bookmarks menu node
PO.selectLeftPaneQuery("BookmarksMenu");
isnot(PO._places.selectedNode, null,
"Correctly selected bookmarks menu node.");
checkInfoBoxSelected(PO);
ok(infoBoxExpanderWrapper.hidden,
"Expander button is hidden for bookmarks menu node.");
checkAddInfoFieldsCollapsed(PO);
// open recently bookmarked node
var menuNode = PO._places.selectedNode.
QueryInterface(Ci.nsINavHistoryContainerResultNode);
menuNode.containerOpen = true;
childNode = menuNode.getChild(0);
isnot(childNode, null, "Bookmarks menu child node exists.");
var recentlyBookmarkedTitle = PlacesUIUtils.
getString("recentlyBookmarkedTitle");
isnot(recentlyBookmarkedTitle, null,
"Correctly got the recently bookmarked title locale string.");
is(childNode.title, recentlyBookmarkedTitle,
"Correctly selected recently bookmarked node.");
PO._places.selectNode(childNode);
checkInfoBoxSelected(PO);
ok(!infoBoxExpanderWrapper.hidden,
"Expander button is not hidden for recently bookmarked node.");
checkAddInfoFieldsNotCollapsed(PO);
// open first bookmark
var view = ContentTree.view.treeBoxObject.view;
ok(view.rowCount > 0, "Bookmark item exists.");
view.selection.select(0);
checkInfoBoxSelected(PO);
ok(!infoBoxExpanderWrapper.hidden,
"Expander button is not hidden for bookmark item.");
checkAddInfoFieldsNotCollapsed(PO);
checkAddInfoFields(PO, "bookmark item");
// make sure additional fields are still hidden in second bookmark item
ok(view.rowCount > 1, "Second bookmark item exists.");
view.selection.select(1);
checkInfoBoxSelected(PO);
ok(!infoBoxExpanderWrapper.hidden,
"Expander button is not hidden for second bookmark item.");
checkAddInfoFieldsNotCollapsed(PO);
checkAddInfoFields(PO, "second bookmark item");
menuNode.containerOpen = false;
waitForClearHistory(nextTest);
addVisits(
{ uri: PlacesUtils._uri(TEST_URI), visitDate: Date.now() * 1000,
transition: PlacesUtils.history.TRANSITION_TYPED },
window,
addVisitsCallback);
}
});

Просмотреть файл

@ -18,53 +18,57 @@ var gLibrary;
gTests.push({
desc: "Bug 489351 - Date containers under History in Library cannot be deleted/cut",
run: function() {
var bhist = PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory);
// Add a visit.
PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_URI), Date.now() * 1000,
null, PlacesUtils.history.TRANSITION_TYPED,
false, 0);
ok(bhist.isVisited(PlacesUtils._uri(TEST_URI)), "Visit has been added");
function addVisitsCallback() {
var bhist = PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory);
// Add a visit.
ok(bhist.isVisited(PlacesUtils._uri(TEST_URI)), "Visit has been added");
// Select and open the left pane "History" query.
var PO = gLibrary.PlacesOrganizer;
PO.selectLeftPaneQuery('History');
isnot(PO._places.selectedNode, null, "We correctly selected History");
// Select and open the left pane "History" query.
var PO = gLibrary.PlacesOrganizer;
PO.selectLeftPaneQuery('History');
isnot(PO._places.selectedNode, null, "We correctly selected History");
// Check that both delete and cut commands are disabled.
ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
"Cut command is disabled");
ok(!PO._places.controller.isCommandEnabled("cmd_delete"),
"Delete command is disabled");
var historyNode = PO._places.selectedNode
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
historyNode.containerOpen = true;
// Check that both delete and cut commands are disabled.
ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
"Cut command is disabled");
ok(!PO._places.controller.isCommandEnabled("cmd_delete"),
"Delete command is disabled");
var historyNode = PO._places.selectedNode
.QueryInterface(Ci.nsINavHistoryContainerResultNode);
historyNode.containerOpen = true;
// Check that we have a child container. It is "Today" container.
is(historyNode.childCount, 1, "History node has one child");
var todayNode = historyNode.getChild(0);
var todayNodeExpectedTitle = PlacesUtils.getString("finduri-AgeInDays-is-0");
is(todayNode.title, todayNodeExpectedTitle,
"History child is the expected container");
// Check that we have a child container. It is "Today" container.
is(historyNode.childCount, 1, "History node has one child");
var todayNode = historyNode.getChild(0);
var todayNodeExpectedTitle = PlacesUtils.getString("finduri-AgeInDays-is-0");
is(todayNode.title, todayNodeExpectedTitle,
"History child is the expected container");
// Select "Today" container.
PO._places.selectNode(todayNode);
is(PO._places.selectedNode, todayNode,
"We correctly selected Today container");
// Check that delete command is enabled but cut command is disabled.
ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
"Cut command is disabled");
ok(PO._places.controller.isCommandEnabled("cmd_delete"),
"Delete command is enabled");
// Select "Today" container.
PO._places.selectNode(todayNode);
is(PO._places.selectedNode, todayNode,
"We correctly selected Today container");
// Check that delete command is enabled but cut command is disabled.
ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
"Cut command is disabled");
ok(PO._places.controller.isCommandEnabled("cmd_delete"),
"Delete command is enabled");
// Execute the delete command and check visit has been removed.
PO._places.controller.doCommand("cmd_delete");
ok(!bhist.isVisited(PlacesUtils._uri(TEST_URI)), "Visit has been removed");
// Execute the delete command and check visit has been removed.
PO._places.controller.doCommand("cmd_delete");
ok(!bhist.isVisited(PlacesUtils._uri(TEST_URI)), "Visit has been removed");
// Test live update of "History" query.
is(historyNode.childCount, 0, "History node has no more children");
// Test live update of "History" query.
is(historyNode.childCount, 0, "History node has no more children");
historyNode.containerOpen = false;
nextTest();
historyNode.containerOpen = false;
nextTest();
}
addVisits(
{uri: PlacesUtils._uri(TEST_URI), visitDate: Date.now() * 1000,
transition: PlacesUtils.history.TRANSITION_TYPED},
window,
addVisitsCallback);
}
});

Просмотреть файл

@ -45,9 +45,11 @@ function test() {
waitForExplicitFinish();
// Add an history entry.
ok(PlacesUtils, "checking PlacesUtils, running in chrome context?");
PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_URI), Date.now() * 1000,
null, PlacesUtils.history.TRANSITION_TYPED,
false, 0);
openLibrary(onLibraryReady);
addVisits(
{uri: PlacesUtils._uri(TEST_URI), visitDate: Date.now() * 1000,
transition: PlacesUtils.history.TRANSITION_TYPED},
window,
function() {
openLibrary(onLibraryReady);
});
}

Просмотреть файл

@ -169,17 +169,19 @@ function test() {
ok(PlacesUtils, "PlacesUtils in context");
// Add visits, a bookmark and a tag.
PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_URL),
Date.now() * 1000, null,
PlacesUtils.history.TRANSITION_TYPED, false, 0);
PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_DOWNLOAD_URL),
Date.now() * 1000, null,
PlacesUtils.history.TRANSITION_DOWNLOAD, false, 0);
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
PlacesUtils._uri(TEST_URL),
PlacesUtils.bookmarks.DEFAULT_INDEX,
"dummy");
PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
addVisits(
[{ uri: PlacesUtils._uri(TEST_URL), visitDate: Date.now() * 1000,
transition: PlacesUtils.history.TRANSITION_TYPED },
{ uri: PlacesUtils._uri(TEST_DOWNLOAD_URL), visitDate: Date.now() * 1000,
transition: PlacesUtils.history.TRANSITION_DOWNLOAD }],
window,
function() {
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
PlacesUtils._uri(TEST_URL),
PlacesUtils.bookmarks.DEFAULT_INDEX,
"dummy");
PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
gLibrary = openLibrary(onLibraryAvailable);
gLibrary = openLibrary(onLibraryAvailable);
});
}

Просмотреть файл

@ -27,12 +27,13 @@ function test() {
tests.push({
_itemID: null,
init: function() {
init: function(aCallback) {
// Add a bookmark to the Unfiled Bookmarks folder.
this._itemID = PlacesUtils.bookmarks.insertBookmark(
PlacesUtils.unfiledBookmarksFolderId, PlacesUtils._uri(TEST_URL),
PlacesUtils.bookmarks.DEFAULT_INDEX, "test"
);
aCallback();
},
prepare: function() {
},
@ -49,13 +50,14 @@ function test() {
});
tests.push({
init: function() {
init: function(aCallback) {
// Add a history entry.
let uri = PlacesUtils._uri(TEST_URL);
PlacesUtils.history.addVisit(uri, Date.now() * 1000, null,
PlacesUtils.history.TRANSITION_TYPED,
false, 0);
ok(PlacesUtils.ghistory2.isVisited(uri), "Item is visited");
addVisits(
{ uri: uri, visitDate: Date.now() * 1000,
transition: PlacesUtils.history.TRANSITION_TYPED },
window,
aCallback);
},
prepare: function() {
sidebar.contentDocument.getElementById("byvisited").doCommand();
@ -74,7 +76,9 @@ function test() {
});
function testPlacesPanel(preFunc, postFunc) {
currentTest.init();
currentTest.init(function() {
toggleSidebar(currentTest.sidebarName);
});
sidebar.addEventListener("load", function() {
sidebar.removeEventListener("load", arguments.callee, true);
@ -113,7 +117,6 @@ function test() {
// for the purpose of this test.
});
}, true);
toggleSidebar(currentTest.sidebarName);
}
function synthesizeClickOnSelectedTreeCell(aTree) {

Просмотреть файл

@ -82,3 +82,66 @@ function waitForAsyncUpdates(aCallback, aScope, aArguments)
});
commit.finalize();
}
/**
* Asynchronously adds visits to a page, invoking a callback function when done.
*
* @param aPlaceInfo
* Can be an nsIURI, in such a case a single LINK visit will be added.
* Otherwise can be an object describing the visit to add, or an array
* of these objects:
* { uri: nsIURI of the page,
* transition: one of the TRANSITION_* from nsINavHistoryService,
* [optional] title: title of the page,
* [optional] visitDate: visit date in microseconds from the epoch
* [optional] referrer: nsIURI of the referrer for this visit
* }
* @param [optional] aCallback
* Function to be invoked on completion.
* @param [optional] aStack
* The stack frame used to report errors.
*/
function addVisits(aPlaceInfo, aWindow, aCallback, aStack) {
let stack = aStack || Components.stack.caller;
let places = [];
if (aPlaceInfo instanceof Ci.nsIURI) {
places.push({ uri: aPlaceInfo });
}
else if (Array.isArray(aPlaceInfo)) {
places = places.concat(aPlaceInfo);
} else {
places.push(aPlaceInfo)
}
// Create mozIVisitInfo for each entry.
let now = Date.now();
for (let i = 0; i < places.length; i++) {
if (!places[i].title) {
places[i].title = "test visit for " + places[i].uri.spec;
}
places[i].visits = [{
transitionType: places[i].transition === undefined ? Ci.nsINavHistoryService.TRANSITION_LINK
: places[i].transition,
visitDate: places[i].visitDate || (now++) * 1000,
referrerURI: places[i].referrer
}];
}
aWindow.PlacesUtils.asyncHistory.updatePlaces(
places,
{
handleError: function AAV_handleError() {
throw("Unexpected error in adding visit.");
},
handleResult: function () {},
handleCompletion: function UP_handleCompletion() {
if (aCallback)
aCallback();
}
}
);
}
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/commonjs/promise/core.js");

Просмотреть файл

@ -11,6 +11,7 @@ relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
MOCHITEST_CHROME_FILES = \
head.js \
test_treeview_date.xul \
test_bug485100-change-case-loses-tag.xul \
test_bug427633_no_newfolder_if_noip.xul \

Просмотреть файл

@ -0,0 +1,55 @@
/**
* Asynchronously adds visits to a page, invoking a callback function when done.
*
* @param aPlaceInfo
* Can be an nsIURI, in such a case a single LINK visit will be added.
* Otherwise can be an object describing the visit to add, or an array
* of these objects:
* { uri: nsIURI of the page,
* transition: one of the TRANSITION_* from nsINavHistoryService,
* [optional] title: title of the page,
* [optional] visitDate: visit date in microseconds from the epoch
* [optional] referrer: nsIURI of the referrer for this visit
* }
* @param [optional] aCallback
* Function to be invoked on completion.
*/
function addVisits(aPlaceInfo, aCallback) {
let places = [];
if (aPlaceInfo instanceof Ci.nsIURI) {
places.push({ uri: aPlaceInfo });
}
else if (Array.isArray(aPlaceInfo)) {
places = places.concat(aPlaceInfo);
} else {
places.push(aPlaceInfo)
}
// Create mozIVisitInfo for each entry.
let now = Date.now();
for (let i = 0; i < places.length; i++) {
if (!places[i].title) {
places[i].title = "test visit for " + places[i].uri.spec;
}
places[i].visits = [{
transitionType: places[i].transition === undefined ? PlacesUtils.history.TRANSITION_LINK
: places[i].transition,
visitDate: places[i].visitDate || (now++) * 1000,
referrerURI: places[i].referrer
}];
}
PlacesUtils.asyncHistory.updatePlaces(
places,
{
handleError: function AAV_handleError() {
throw("Unexpected error in adding visit.");
},
handleResult: function () {},
handleCompletion: function UP_handleCompletion() {
if (aCallback)
aCallback();
}
}
);
}

Просмотреть файл

@ -19,6 +19,7 @@
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript" src="head.js" />
<body xmlns="http://www.w3.org/1999/xhtml" />
@ -51,46 +52,46 @@
// Add some visits.
let vtime = Date.now() * 1000;
const ttype = PlacesUtils.history.TRANSITION_TYPED;
PlacesUtils.history
.addVisit(Services.io.newURI("http://example.tld/", null, null),
vtime, null, ttype, false, 0);
PlacesUtils.history
.addVisit(Services.io.newURI("http://example2.tld/", null, null),
vtime++, null, ttype, false, 0);
PlacesUtils.history
.addVisit(Services.io.newURI("http://exmample3.tld/", null, null),
vtime++, null, ttype, false, 0);
// Make a history query.
let query = PlacesUtils.history.getNewQuery();
let opts = PlacesUtils.history.getNewQueryOptions();
let queryURI = PlacesUtils.history.queriesToQueryString([query], 1, opts);
addVisits(
[{ uri: Services.io.newURI("http://example.tld/", null, null),
visitDate: vtime, transition: ttype },
{ uri: Services.io.newURI("http://example2.tld/", null, null),
visitDate: vtime++, transition: ttype },
{ uri: Services.io.newURI("http://example3.tld/", null, null),
visitDate: vtime++, transition: ttype }],
function() {
// Make a history query.
let query = PlacesUtils.history.getNewQuery();
let opts = PlacesUtils.history.getNewQueryOptions();
let queryURI = PlacesUtils.history.queriesToQueryString([query], 1, opts);
// Setup the places tree contents.
var tree = document.getElementById("tree");
tree.place = queryURI;
// Setup the places tree contents.
var tree = document.getElementById("tree");
tree.place = queryURI;
// loop through the rows and check formatting
let treeView = tree.view;
for (let i = 0; i < rc; i++) {
selection.select(rc);
let node = tree.selectedNode;
ok(true, "found " + node.title);
}
let rc = treeView.rowCount;
is(rc, 3, "Rows found.");
let selection = treeView.selection;
for (let i = 0; i < rc; i++) {
selection.select(0);
let node = tree.selectedNode;
tree.controller.remove("Removing page");
ok(treeView.treeIndexForNode(node) == Ci.nsINavHistoryResultTreeViewer.INDEX_INVISIBLE,
node.uri + " removed.");
ok(treeView.rowCount == rc - i - 1, "Rows count decreased");
}
// loop through the rows and check formatting
let treeView = tree.view;
for (let i = 0; i < rc; i++) {
selection.select(rc);
let node = tree.selectedNode;
ok(true, "found " + node.title);
}
let rc = treeView.rowCount;
is(rc, 3, "Rows found.");
let selection = treeView.selection;
for (let i = 0; i < rc; i++) {
selection.select(0);
let node = tree.selectedNode;
tree.controller.remove("Removing page");
ok(treeView.treeIndexForNode(node) == Ci.nsINavHistoryResultTreeViewer.INDEX_INVISIBLE,
node.uri + " removed.");
ok(treeView.rowCount == rc - i - 1, "Rows count decreased");
}
// Cleanup.
waitForClearHistory(SimpleTest.finish);
// Cleanup.
waitForClearHistory(SimpleTest.finish);
});
}
/**

Просмотреть файл

@ -19,6 +19,7 @@
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript" src="head.js" />
<body xmlns="http://www.w3.org/1999/xhtml" />
@ -51,27 +52,28 @@
}
function continue_test() {
PlacesUtils.history
.addVisit(Services.io.newURI("http://example.tld/", null, null),
Date.now() * 1000, null, PlacesUtils.history.TRANSITION_TYPED, false, 0);
addVisits(
{uri: Services.io.newURI("http://example.tld/", null, null),
transition: PlacesUtils.history.TRANSITION_TYPED},
function() {
// Make a history query.
let query = PlacesUtils.history.getNewQuery();
let opts = PlacesUtils.history.getNewQueryOptions();
let queryURI = PlacesUtils.history.queriesToQueryString([query], 1, opts);
// Make a history query.
let query = PlacesUtils.history.getNewQuery();
let opts = PlacesUtils.history.getNewQueryOptions();
let queryURI = PlacesUtils.history.queriesToQueryString([query], 1, opts);
// Setup the places tree contents.
let tree = document.getElementById("tree");
tree.place = queryURI;
// Setup the places tree contents.
let tree = document.getElementById("tree");
tree.place = queryURI;
let rootNode = tree.result.root;
let obs = tree.view.QueryInterface(Ci.nsINavHistoryResultObserver);
obs.nodeHistoryDetailsChanged(rootNode, rootNode.time, rootNode.accessCount);
obs.nodeTitleChanged(rootNode, rootNode.title);
ok(true, "No exceptions thrown");
let rootNode = tree.result.root;
let obs = tree.view.QueryInterface(Ci.nsINavHistoryResultObserver);
obs.nodeHistoryDetailsChanged(rootNode, rootNode.time, rootNode.accessCount);
obs.nodeTitleChanged(rootNode, rootNode.title);
ok(true, "No exceptions thrown");
// Cleanup.
waitForClearHistory(SimpleTest.finish);
// Cleanup.
waitForClearHistory(SimpleTest.finish);
});
}
/**

Просмотреть файл

@ -18,6 +18,7 @@
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript" src="head.js" />
<body xmlns="http://www.w3.org/1999/xhtml" />
@ -77,91 +78,92 @@
midnight.setSeconds(0);
midnight.setMilliseconds(0);
// Add a visit 1ms before midnight.
hs.addVisit(uri("http://before.midnight.com/"),
(midnight.getTime() - 1) * 1000,
null, hs.TRANSITION_TYPED, false, 0);
function addVisitsCallback() {
// add a bookmark to the midnight visit
var itemId = bs.insertBookmark(bs.toolbarFolder,
uri("http://at.midnight.com/"),
bs.DEFAULT_INDEX,
"A bookmark at midnight");
// Add a visit at midnight.
hs.addVisit(uri("http://at.midnight.com/"),
(midnight.getTime()) * 1000,
null, hs.TRANSITION_TYPED, false, 0);
// Make a history query.
var query = hs.getNewQuery();
var opts = hs.getNewQueryOptions();
var queryURI = hs.queriesToQueryString([query], 1, opts);
// Add a visit 1ms after midnight.
hs.addVisit(uri("http://after.midnight.com/"),
(midnight.getTime() + 1) * 1000,
null, hs.TRANSITION_TYPED, false, 0);
// Setup the places tree contents.
var tree = document.getElementById("tree");
tree.place = queryURI;
// add a bookmark to the midnight visit
var itemId = bs.insertBookmark(bs.toolbarFolder,
uri("http://at.midnight.com/"),
bs.DEFAULT_INDEX,
"A bookmark at midnight");
// Make a history query.
var query = hs.getNewQuery();
var opts = hs.getNewQueryOptions();
var queryURI = hs.queriesToQueryString([query], 1, opts);
// Setup the places tree contents.
var tree = document.getElementById("tree");
tree.place = queryURI;
// loop through the rows and check formatting
var treeView = tree.view;
var rc = treeView.rowCount;
ok(rc >= 3, "Rows found");
var columns = tree.columns;
ok(columns.count > 0, "Columns found");
for (var r = 0; r < rc; r++) {
var node = treeView.nodeForTreeIndex(r);
ok(node, "Places node found");
for (var ci = 0; ci < columns.count; ci++) {
var c = columns.getColumnAt(ci);
var text = treeView.getCellText(r, c);
switch (c.element.getAttribute("anonid")) {
case "title":
// The title can differ, we did not set any title so we would
// expect null, but in such a case the view will generate a title
// through PlacesUIUtils.getBestTitle.
if (node.title)
is(text, node.title, "Title is correct");
break;
case "url":
is(text, node.uri, "Uri is correct");
break;
case "date":
var timeObj = new Date(node.time / 1000);
// Default is short date format.
var dateFormat = Ci.nsIScriptableDateFormat.dateFormatShort;
// For today's visits we don't show date portion.
if (node.uri == "http://at.midnight.com/" ||
node.uri == "http://after.midnight.com/")
dateFormat = Ci.nsIScriptableDateFormat.dateFormatNone;
else if (node.uri == "http://before.midnight.com/")
dateFormat = Ci.nsIScriptableDateFormat.dateFormatShort;
else {
// Avoid to test spurious uris, due to how the test works
// a redirecting uri could be put in the tree while we test.
// loop through the rows and check formatting
var treeView = tree.view;
var rc = treeView.rowCount;
ok(rc >= 3, "Rows found");
var columns = tree.columns;
ok(columns.count > 0, "Columns found");
for (var r = 0; r < rc; r++) {
var node = treeView.nodeForTreeIndex(r);
ok(node, "Places node found");
for (var ci = 0; ci < columns.count; ci++) {
var c = columns.getColumnAt(ci);
var text = treeView.getCellText(r, c);
switch (c.element.getAttribute("anonid")) {
case "title":
// The title can differ, we did not set any title so we would
// expect null, but in such a case the view will generate a title
// through PlacesUIUtils.getBestTitle.
if (node.title)
is(text, node.title, "Title is correct");
break;
}
var timeStr = ds.FormatDateTime("", dateFormat,
Ci.nsIScriptableDateFormat.timeFormatNoSeconds,
timeObj.getFullYear(), timeObj.getMonth() + 1,
timeObj.getDate(), timeObj.getHours(),
timeObj.getMinutes(), timeObj.getSeconds())
case "url":
is(text, node.uri, "Uri is correct");
break;
case "date":
var timeObj = new Date(node.time / 1000);
// Default is short date format.
var dateFormat = Ci.nsIScriptableDateFormat.dateFormatShort;
// For today's visits we don't show date portion.
if (node.uri == "http://at.midnight.com/" ||
node.uri == "http://after.midnight.com/")
dateFormat = Ci.nsIScriptableDateFormat.dateFormatNone;
else if (node.uri == "http://before.midnight.com/")
dateFormat = Ci.nsIScriptableDateFormat.dateFormatShort;
else {
// Avoid to test spurious uris, due to how the test works
// a redirecting uri could be put in the tree while we test.
break;
}
var timeStr = ds.FormatDateTime("", dateFormat,
Ci.nsIScriptableDateFormat.timeFormatNoSeconds,
timeObj.getFullYear(), timeObj.getMonth() + 1,
timeObj.getDate(), timeObj.getHours(),
timeObj.getMinutes(), timeObj.getSeconds())
is(text, timeStr, "Date format is correct");
break;
case "visitCount":
is(text, 1, "Visit count is correct");
break;
is(text, timeStr, "Date format is correct");
break;
case "visitCount":
is(text, 1, "Visit count is correct");
break;
}
}
}
// Cleanup.
bs.removeItem(itemId);
waitForClearHistory(SimpleTest.finish);
}
// Cleanup.
bs.removeItem(itemId);
waitForClearHistory(SimpleTest.finish);
// Add a visit 1ms before midnight, a visit at midnight, and
// a visit 1ms after midnight.
addVisits(
[{uri: uri("http://before.midnight.com/"),
visitDate: (midnight.getTime() - 1) * 1000,
transition: hs.TRANSITION_TYPED},
{uri: uri("http://at.midnight.com/"),
visitDate: (midnight.getTime()) * 1000,
transition: hs.TRANSITION_TYPED},
{uri: uri("http://after.midnight.com/"),
visitDate: (midnight.getTime() + 1) * 1000,
transition: hs.TRANSITION_TYPED}],
addVisitsCallback);
}
/**

Просмотреть файл

@ -73,6 +73,10 @@ let notificationsObserver = {
let timeInMicroseconds = Date.now() * 1000;
function run_test() {
run_next_test();
}
add_task(function test_execute() {
do_test_pending();
print("Initialize browserglue before Places");
@ -96,14 +100,13 @@ function run_test() {
Services.prefs.setBoolPref("privacy.sanitize.sanitizeOnShutdown", true);
print("Add visits.");
URIS.forEach(function(aUrl) {
PlacesUtils.history.addVisit(uri(aUrl), timeInMicroseconds++, null,
PlacesUtils.history.TRANSITION_TYPED,
false, 0);
});
for (let aUrl of URIS) {
yield promiseAddVisits({uri: uri(aUrl), visitDate: timeInMicroseconds++,
transition: PlacesUtils.history.TRANSITION_TYPED})
}
print("Add cache.");
storeCache(URL, "testData");
}
});
function run_test_continue()
{

Просмотреть файл

@ -12,6 +12,7 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_BROWSER_FILES = \
head.js \
browser_advanced_update.js \
browser_bug410900.js \
browser_bug705422.js \

Просмотреть файл

@ -28,27 +28,28 @@ const TEST_PERMS = {
function test() {
waitForExplicitFinish();
registerCleanupFunction(cleanUp);
setup();
runNextTest();
setup(function() {
runNextTest();
});
}
function setup() {
function setup(aCallback) {
// add test history visit
PlacesUtils.history.addVisit(TEST_URI_1, Date.now() * 1000, null,
Ci.nsINavHistoryService.TRANSITION_LINK, false, 0);
// set permissions ourselves to avoid problems with different defaults
// from test harness configuration
for (let type in TEST_PERMS) {
if (type == "password") {
Services.logins.setLoginSavingEnabled(TEST_URI_2.prePath, true);
} else {
// set permissions on a site without history visits to test enumerateServices
Services.perms.add(TEST_URI_2, type, TEST_PERMS[type]);
addVisits(TEST_URI_1, function() {
// set permissions ourselves to avoid problems with different defaults
// from test harness configuration
for (let type in TEST_PERMS) {
if (type == "password") {
Services.logins.setLoginSavingEnabled(TEST_URI_2.prePath, true);
} else {
// set permissions on a site without history visits to test enumerateServices
Services.perms.add(TEST_URI_2, type, TEST_PERMS[type]);
}
}
}
Services.perms.add(TEST_URI_3, "popup", TEST_PERMS["popup"]);
Services.perms.add(TEST_URI_3, "popup", TEST_PERMS["popup"]);
aCallback();
});
}
function cleanUp() {

Просмотреть файл

@ -44,28 +44,27 @@ function test() {
registerCleanupFunction(cleanUp);
// add test history visit
PlacesUtils.history.addVisit(TEST_URI_1, Date.now() * 1000, null,
Ci.nsINavHistoryService.TRANSITION_LINK, false, 0);
// set permissions ourselves to avoid problems with different defaults
// from test harness configuration
for (let type in TEST_PERMS) {
if (type == "password") {
Services.logins.setLoginSavingEnabled(TEST_URI_2.prePath, true);
} else {
// set permissions on a site without history visits to test enumerateServices
Services.perms.addFromPrincipal(TEST_PRINCIPAL_2, type, TEST_PERMS[type]);
addVisits(TEST_URI_1, function() {
// set permissions ourselves to avoid problems with different defaults
// from test harness configuration
for (let type in TEST_PERMS) {
if (type == "password") {
Services.logins.setLoginSavingEnabled(TEST_URI_2.prePath, true);
} else {
// set permissions on a site without history visits to test enumerateServices
Services.perms.addFromPrincipal(TEST_PRINCIPAL_2, type, TEST_PERMS[type]);
}
}
}
// open about:permissions
gBrowser.selectedTab = gBrowser.addTab("about:permissions");
});
function observer() {
Services.obs.removeObserver(observer, "browser-permissions-initialized", false);
runNextTest();
}
Services.obs.addObserver(observer, "browser-permissions-initialized", false);
// open about:permissions
gBrowser.selectedTab = gBrowser.addTab("about:permissions");
}
function cleanUp() {

Просмотреть файл

@ -0,0 +1,57 @@
Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
/**
* Asynchronously adds visits to a page, invoking a callback function when done.
*
* @param aPlaceInfo
* Can be an nsIURI, in such a case a single LINK visit will be added.
* Otherwise can be an object describing the visit to add, or an array
* of these objects:
* { uri: nsIURI of the page,
* transition: one of the TRANSITION_* from nsINavHistoryService,
* [optional] title: title of the page,
* [optional] visitDate: visit date in microseconds from the epoch
* [optional] referrer: nsIURI of the referrer for this visit
* }
* @param [optional] aCallback
* Function to be invoked on completion.
*/
function addVisits(aPlaceInfo, aCallback) {
let places = [];
if (aPlaceInfo instanceof Ci.nsIURI) {
places.push({ uri: aPlaceInfo });
}
else if (Array.isArray(aPlaceInfo)) {
places = places.concat(aPlaceInfo);
} else {
places.push(aPlaceInfo)
}
// Create mozIVisitInfo for each entry.
let now = Date.now();
for (let i = 0; i < places.length; i++) {
if (!places[i].title) {
places[i].title = "test visit for " + places[i].uri.spec;
}
places[i].visits = [{
transitionType: places[i].transition === undefined ? PlacesUtils.history.TRANSITION_LINK
: places[i].transition,
visitDate: places[i].visitDate || (now++) * 1000,
referrerURI: places[i].referrer
}];
}
PlacesUtils.asyncHistory.updatePlaces(
places,
{
handleError: function AAV_handleError() {
throw("Unexpected error in adding visit.");
},
handleResult: function () {},
handleCompletion: function UP_handleCompletion() {
if (aCallback)
aCallback();
}
}
);
}

Просмотреть файл

@ -19,7 +19,7 @@ function test() {
let pb = Cc["@mozilla.org/privatebrowsing;1"].
getService(Ci.nsIPrivateBrowsingService);
MockFilePicker.init();
MockFilePicker.init(window);
MockFilePicker.returnValue = Ci.nsIFilePicker.returnOK;
Services.prefs.setBoolPref("browser.privatebrowsing.keep_current_session", true);

Просмотреть файл

@ -16,7 +16,7 @@ function test() {
let pb = Cc["@mozilla.org/privatebrowsing;1"].
getService(Ci.nsIPrivateBrowsingService);
MockFilePicker.init();
MockFilePicker.init(window);
MockFilePicker.returnValue = Ci.nsIFilePicker.returnOK;
//let stringBundleToRestore = ContentAreaUtils.stringBundle;

Просмотреть файл

@ -32,10 +32,34 @@ function test() {
// Add a history entry.
const TEST_URI = "http://www.mozilla.org/privatebrowsing";
ok(PlacesUtils, "checking PlacesUtils, running in chrome context?");
let history = PlacesUtils.history;
let visitId = history.addVisit(PlacesUtils._uri(TEST_URI), Date.now() * 1000,
null, PlacesUtils.history.TRANSITION_TYPED, false, 0);
ok(visitId > 0, TEST_URI + " successfully marked visited");
let place = {
uri: PlacesUtils._uri(TEST_URI),
visits: [{
visitDate: Date.now() * 1000,
transitionType: PlacesUtils.history.TRANSITION_TYPED
}]
}
PlacesUtils.asyncHistory.updatePlaces(place, {
handleError: function () ok(false, "couldn't add visit"),
handleResult: function () {},
handleCompletion: function () {
ok(true, TEST_URI + " successfully marked visited");
testForgetThisSiteVisibility(true, function() {
// Enter private browsing mode
pb.privateBrowsingEnabled = true;
testForgetThisSiteVisibility(false, function() {
// Leave private browsing mode
pb.privateBrowsingEnabled = false;
testForgetThisSiteVisibility(true, function() {
// Cleanup
waitForClearHistory(finish);
});
});
});
}
});
function testForgetThisSiteVisibility(expected, funcNext) {
function observer(aSubject, aTopic, aData) {
@ -102,17 +126,4 @@ function test() {
"chrome,toolbar=yes,dialog=no,resizable",
null);
}
testForgetThisSiteVisibility(true, function() {
// Enter private browsing mode
pb.privateBrowsingEnabled = true;
testForgetThisSiteVisibility(false, function() {
// Leave private browsing mode
pb.privateBrowsingEnabled = false;
testForgetThisSiteVisibility(true, function() {
// Cleanup
waitForClearHistory(finish);
});
});
});
}

Просмотреть файл

@ -15,7 +15,7 @@ function test() {
source: Services.io.newURI("http://test1.com/file", null, null)
};
MockFilePicker.init();
MockFilePicker.init(window);
MockFilePicker.returnValue = Ci.nsIFilePicker.returnOK;
let prefs = Services.prefs.getBranch("browser.download.");

Просмотреть файл

@ -12,7 +12,7 @@ function test() {
Cu.import("resource://gre/modules/DownloadLastDir.jsm", {}).DownloadLastDir;
let MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init();
MockFilePicker.init(window);
MockFilePicker.returnValue = Ci.nsIFilePicker.returnOK;
let validateFileNameToRestore = validateFileName;

Просмотреть файл

@ -5,7 +5,6 @@ tail = tail_privatebrowsing.js
[test_0-privatebrowsing.js]
[test_0-privatebrowsingwrapper.js]
[test_aboutprivatebrowsing.js]
[test_httpauth.js]
[test_placesTitleNoUpdate.js]
[test_privatebrowsing_autostart.js]
[test_privatebrowsing_commandline.js]

Просмотреть файл

@ -110,6 +110,10 @@ function debug(aMsg) {
}
this.SessionStore = {
get promiseInitialized() {
return SessionStoreInternal.promiseInitialized.promise;
},
get canRestoreLastSession() {
return SessionStoreInternal.canRestoreLastSession;
},
@ -312,6 +316,13 @@ let SessionStoreInternal = {
// "sessionstore.resume_from_crash" is true.
_resume_session_once_on_shutdown: null,
/**
* A promise fulfilled once initialization is complete.
*/
get promiseInitialized() {
return this._promiseInitialization;
},
/* ........ Public Getters .............. */
get canRestoreLastSession() {
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING

Просмотреть файл

@ -14,7 +14,6 @@ include $(DEPTH)/config/autoconf.mk
# browser_526613.js is disabled because of frequent failures (bug 534489)
# browser_589246.js is disabled for leaking browser windows (bug 752467)
# browser_580512.js is disabled for leaking browser windows (bug 752467)
# browser_586068-reload.js is disabled due to generally being broken (bug 809123, 797263)
XPCSHELL_TESTS = \
unit \
@ -89,6 +88,7 @@ MOCHITEST_BROWSER_FILES = \
browser_586068-browser_state_interrupted.js \
browser_586068-cascade.js \
browser_586068-multi_window.js \
browser_586068-reload.js \
browser_586068-select.js \
browser_586068-window_state.js \
browser_586068-window_state_override.js \

Просмотреть файл

@ -4,11 +4,11 @@
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
let stateBackup = ss.getBrowserState();
function test() {
waitForExplicitFinish();
TestRunner.run();
}
function runTests() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
registerCleanupFunction(function () {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
@ -46,10 +46,8 @@ function test() {
return;
gProgressListener.unsetCallback();
executeSoon(function () {
waitForBrowserState(JSON.parse(stateBackup), finish);
});
executeSoon(next);
});
ss.setBrowserState(JSON.stringify(state));
yield ss.setBrowserState(JSON.stringify(state));
}

Просмотреть файл

@ -5,11 +5,11 @@
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
const PREF_RESTORE_PINNED_TABS_ON_DEMAND = "browser.sessionstore.restore_pinned_tabs_on_demand";
let stateBackup = ss.getBrowserState();
function test() {
waitForExplicitFinish();
TestRunner.run();
}
function runTests() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
Services.prefs.setBoolPref(PREF_RESTORE_PINNED_TABS_ON_DEMAND, true);
@ -43,10 +43,8 @@ function test() {
is(aRestored, 0, "no tabs have been restored, yet");
gProgressListener.unsetCallback();
executeSoon(function () {
waitForBrowserState(JSON.parse(stateBackup), finish);
});
executeSoon(next);
});
ss.setBrowserState(JSON.stringify(state));
yield ss.setBrowserState(JSON.stringify(state));
}

Просмотреть файл

@ -4,11 +4,11 @@
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
let stateBackup = ss.getBrowserState();
function test() {
waitForExplicitFinish();
TestRunner.run();
}
function runTests() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
registerCleanupFunction(function () {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
@ -89,10 +89,7 @@ function test() {
// Remove the progress listener from this window, it will be removed from
// theWin when that window is closed (in setBrowserState).
gProgressListener.unsetCallback();
executeSoon(function () {
closeAllButPrimaryWindow();
waitForBrowserState(JSON.parse(stateBackup), finish);
});
executeSoon(next);
});
// We also want to catch the extra windows (there should be 2), so we need to observe domwindowopened
@ -107,5 +104,5 @@ function test() {
}
});
ss.setBrowserState(JSON.stringify(state1));
yield ss.setBrowserState(JSON.stringify(state1));
}

Просмотреть файл

@ -4,11 +4,11 @@
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
let stateBackup = ss.getBrowserState();
function test() {
waitForExplicitFinish();
TestRunner.run();
}
function runTests() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
registerCleanupFunction(function () {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
@ -43,11 +43,9 @@ function test() {
if (loadCount == state.windows[0].tabs.length) {
gProgressListener.unsetCallback();
executeSoon(function () {
waitForBrowserState(JSON.parse(stateBackup), finish);
});
executeSoon(next);
}
});
ss.setBrowserState(JSON.stringify(state));
yield ss.setBrowserState(JSON.stringify(state));
}

Просмотреть файл

@ -4,11 +4,11 @@
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
let stateBackup = ss.getBrowserState();
function test() {
waitForExplicitFinish();
TestRunner.run();
}
function runTests() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
registerCleanupFunction(function () {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
@ -46,10 +46,7 @@ function test() {
is(aNeedRestore, 0, "there are no tabs left needing restore");
gProgressListener.unsetCallback();
executeSoon(function () {
closeAllButPrimaryWindow();
waitForBrowserState(JSON.parse(stateBackup), finish);
});
executeSoon(next);
}
});
@ -65,5 +62,5 @@ function test() {
}
});
ss.setBrowserState(JSON.stringify(state));
yield ss.setBrowserState(JSON.stringify(state));
}

Просмотреть файл

@ -4,10 +4,15 @@
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
let stateBackup = ss.getBrowserState();
function test() {
waitForExplicitFinish();
TestRunner.run();
}
function runTests() {
// Request a longer timeout because the test takes quite a while
// to complete on slow Windows debug machines and we would otherwise
// see a lot of (not so) intermittent test failures.
requestLongerTimeout(2);
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
registerCleanupFunction(function () {
@ -56,7 +61,7 @@ function test() {
gProgressListener.unsetCallback();
executeSoon(function () {
reloadAllTabs(state, function () {
waitForBrowserState(JSON.parse(stateBackup), testCascade);
waitForBrowserState(TestRunner.backupState, testCascade);
});
});
} else {
@ -66,7 +71,7 @@ function test() {
}
});
ss.setBrowserState(JSON.stringify(state));
yield ss.setBrowserState(JSON.stringify(state));
}
function testCascade() {
@ -89,9 +94,7 @@ function testCascade() {
gProgressListener.unsetCallback();
executeSoon(function () {
reloadAllTabs(state, function () {
waitForBrowserState(JSON.parse(stateBackup), finish);
});
reloadAllTabs(state, next);
});
});

Просмотреть файл

@ -4,11 +4,11 @@
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
let stateBackup = ss.getBrowserState();
function test() {
waitForExplicitFinish();
TestRunner.run();
}
function runTests() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
registerCleanupFunction(function () {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
@ -58,11 +58,9 @@ function test() {
window.gBrowser.selectTabAtIndex(tabOrder[loadCount]);
} else {
gProgressListener.unsetCallback();
executeSoon(function () {
waitForBrowserState(JSON.parse(stateBackup), finish);
});
executeSoon(next);
}
});
ss.setBrowserState(JSON.stringify(state));
yield ss.setBrowserState(JSON.stringify(state));
}

Просмотреть файл

@ -4,11 +4,11 @@
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
let stateBackup = ss.getBrowserState();
function test() {
waitForExplicitFinish();
TestRunner.run();
}
function runTests() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
registerCleanupFunction(function () {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
@ -53,10 +53,8 @@ function test() {
is(aNeedRestore, 0, "there are no tabs left needing restore");
gProgressListener.unsetCallback();
executeSoon(function () {
waitForBrowserState(JSON.parse(stateBackup), finish);
});
executeSoon(next);
});
ss.setWindowState(window, JSON.stringify(state1), true);
yield ss.setWindowState(window, JSON.stringify(state1), true);
}

Просмотреть файл

@ -4,11 +4,11 @@
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
let stateBackup = ss.getBrowserState();
function test() {
waitForExplicitFinish();
TestRunner.run();
}
function runTests() {
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
registerCleanupFunction(function () {
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
@ -53,10 +53,8 @@ function test() {
is(aNeedRestore, 0, "there are no tabs left needing restore");
gProgressListener.unsetCallback();
executeSoon(function () {
waitForBrowserState(JSON.parse(stateBackup), finish);
});
executeSoon(next);
});
ss.setWindowState(window, JSON.stringify(state1), true);
yield ss.setWindowState(window, JSON.stringify(state1), true);
}

Просмотреть файл

@ -5,6 +5,10 @@
const TAB_STATE_NEEDS_RESTORE = 1;
const TAB_STATE_RESTORING = 2;
let tmp = {};
Cu.import("resource:///modules/sessionstore/SessionStore.jsm", tmp);
let SessionStore = tmp.SessionStore;
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
// Some tests here assume that all restored tabs are loaded without waiting for
@ -285,3 +289,54 @@ function whenNewWindowLoaded(aIsPrivate, aCallback) {
aCallback(win);
}, false);
}
/**
* The test runner that controls the execution flow of our tests.
*/
let TestRunner = {
_iter: null,
/**
* Holds the browser state from before we started so
* that we can restore it after all tests ran.
*/
backupState: {},
/**
* Starts the test runner.
*/
run: function () {
waitForExplicitFinish();
SessionStore.promiseInitialized.then(function () {
executeSoon(function () {
this.backupState = JSON.parse(ss.getBrowserState());
this._iter = runTests();
this.next();
}.bind(this));
}.bind(this));
},
/**
* Runs the next available test or finishes if there's no test left.
*/
next: function () {
try {
TestRunner._iter.next();
} catch (e if e instanceof StopIteration) {
TestRunner.finish();
}
},
/**
* Finishes all tests and cleans up.
*/
finish: function () {
closeAllButPrimaryWindow();
waitForBrowserState(this.backupState, finish);
}
};
function next() {
TestRunner.next();
}

Просмотреть файл

@ -45,16 +45,18 @@ function runTests() {
yield clearHistory(true);
// Retry until the file is gone because Windows locks it sometimes.
while (file.exists()) {
clearFile(file, URL);
}
function clearFile(aFile, aURL) {
if (aFile.exists())
// Re-add our URL to the history so that history observer's onDeleteURI()
// is called again.
let time = Date.now() * 1000;
let trans = Ci.nsINavHistoryService.TRANSITION_LINK;
PlacesUtils.history.addVisit(makeURI(URL), time, null, trans, false, 0);
// Try again...
yield clearHistory(true);
}
addVisits(makeURI(aURL), function() {
// Try again...
yield clearHistory(true);
clearFile(aFile, aURL);
});
}
function clearHistory(aUseRange) {

Просмотреть файл

@ -6,6 +6,8 @@ Cu.import("resource:///modules/PageThumbs.jsm", tmp);
let PageThumbs = tmp.PageThumbs;
let PageThumbsStorage = tmp.PageThumbsStorage;
Cu.import("resource://gre/modules/PlacesUtils.jsm");
registerCleanupFunction(function () {
while (gBrowser.tabs.length > 1)
gBrowser.removeTab(gBrowser.tabs[1]);
@ -155,3 +157,60 @@ function thumbnailExists(aURL) {
let file = PageThumbsStorage.getFileForURL(aURL);
return file.exists() && file.fileSize;
}
/**
* Asynchronously adds visits to a page, invoking a callback function when done.
*
* @param aPlaceInfo
* Can be an nsIURI, in such a case a single LINK visit will be added.
* Otherwise can be an object describing the visit to add, or an array
* of these objects:
* { uri: nsIURI of the page,
* transition: one of the TRANSITION_* from nsINavHistoryService,
* [optional] title: title of the page,
* [optional] visitDate: visit date in microseconds from the epoch
* [optional] referrer: nsIURI of the referrer for this visit
* }
* @param [optional] aCallback
* Function to be invoked on completion.
*/
function addVisits(aPlaceInfo, aCallback) {
let places = [];
if (aPlaceInfo instanceof Ci.nsIURI) {
places.push({ uri: aPlaceInfo });
}
else if (Array.isArray(aPlaceInfo)) {
places = places.concat(aPlaceInfo);
} else {
places.push(aPlaceInfo)
}
// Create mozIVisitInfo for each entry.
let now = Date.now();
for (let i = 0; i < places.length; i++) {
if (!places[i].title) {
places[i].title = "test visit for " + places[i].uri.spec;
}
places[i].visits = [{
transitionType: places[i].transition === undefined ? PlacesUtils.history.TRANSITION_LINK
: places[i].transition,
visitDate: places[i].visitDate || (now++) * 1000,
referrerURI: places[i].referrer
}];
}
PlacesUtils.asyncHistory.updatePlaces(
places,
{
handleError: function AAV_handleError() {
throw("Unexpected error in adding visit.");
},
handleResult: function () {},
handleCompletion: function UP_handleCompletion() {
if (aCallback)
aCallback();
}
}
);
}

Просмотреть файл

@ -1259,6 +1259,41 @@ XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
}
});
/**
* 'dbg list' command
*/
gcli.addCommand({
name: "dbg list",
description: gcli.lookup("dbgListSourcesDesc"),
params: [],
returnType: "html",
exec: function(args, context) {
let dbg = getPanel(context, "jsdebugger");
let doc = context.environment.chromeDocument;
if (!dbg) {
return gcli.lookup("debuggerClosed");
}
let sources = dbg._view.Sources.values;
let div = createXHTMLElement(doc, "div");
let ol = createXHTMLElement(doc, "ol");
sources.forEach(function(src) {
let li = createXHTMLElement(doc, "li");
li.textContent = src;
ol.appendChild(li);
});
div.appendChild(ol);
return div;
}
});
/**
* A helper to create xhtml namespaced elements
*/
function createXHTMLElement(document, tagname) {
return document.createElementNS("http://www.w3.org/1999/xhtml", tagname);
}
/**
* A helper to go from a command context to a debugger panel
*/

Просмотреть файл

@ -18,12 +18,17 @@ function test() {
function testCommands(dbg, cmd) {
// Wait for the initial resume...
dbg._controller.activeThread.addOneTimeListener("resumed", function () {
info("Starting tests.");
info("Starting tests");
let contentDoc = content.window.document;
let output = contentDoc.querySelector("input[type=text]");
let btnDoit = contentDoc.querySelector("input[type=button]");
DeveloperToolbarTest.exec({
typed: "dbg list",
outputMatch: /browser_dbg_cmd.html/
});
cmd("dbg interrupt", function() {
ok(true, "debugger is paused");
dbg._controller.activeThread.addOneTimeListener("resumed", function () {

Просмотреть файл

@ -661,13 +661,12 @@ StackFrames.prototype = {
// to contain all the values.
if (this.syncedWatchExpressions && watchExpressionsEvaluation) {
let label = L10N.getStr("watchExpressionsScopeLabel");
let arrow = L10N.getStr("watchExpressionsSeparatorLabel");
let scope = DebuggerView.Variables.addScope(label);
scope.separator = arrow;
scope.showDescriptorTooltip = false;
scope.allowNameInput = true;
scope.allowDeletion = true;
scope.contextMenu = "debuggerWatchExpressionsContextMenu";
// Customize the scope for holding watch expressions evaluations.
scope.descriptorTooltip = false;
scope.contextMenuId = "debuggerWatchExpressionsContextMenu";
scope.separatorStr = L10N.getStr("watchExpressionsSeparatorLabel");
scope.switch = DebuggerView.WatchExpressions.switchExpression;
scope.delete = DebuggerView.WatchExpressions.deleteExpression;
@ -769,6 +768,12 @@ StackFrames.prototype = {
let expVal = ownProperties[i].value;
let expRef = aScope.addVar(name, ownProperties[i]);
this._addVarExpander(expRef, expVal);
// Revert some of the custom watch expressions scope presentation flags.
expRef.switch = null;
expRef.delete = null;
expRef.descriptorTooltip = true;
expRef.separatorStr = L10N.getStr("variablesSeparatorLabel");
}
// Signal that watch expressions have been fetched.

Просмотреть файл

@ -26,7 +26,7 @@ function testSimpleCall() {
let testScope = gDebugger.DebuggerView.Variables.addScope("test");
let testVar = testScope.addVar("something");
testVar._setGrip(1.618);
testVar.setGrip(1.618);
is(testVar.target.querySelector(".value").getAttribute("value"), "1.618",
"The grip information for the variable wasn't set correctly.");
@ -35,7 +35,7 @@ function testSimpleCall() {
"Adding a value property shouldn't add any new tree nodes.");
testVar._setGrip({ "type": "object", "class": "Window" });
testVar.setGrip({ "type": "object", "class": "Window" });
is(testVar.target.querySelector(".details").childNodes.length, 0,
"Adding type and class properties shouldn't add any new tree nodes.");

Просмотреть файл

@ -35,13 +35,13 @@ function testSimpleCall() {
let localVar4 = localScope.addVar("localVar4");
let localVar5 = localScope.addVar("localVar5");
localVar0._setGrip(42);
localVar1._setGrip(true);
localVar2._setGrip("nasu");
localVar0.setGrip(42);
localVar1.setGrip(true);
localVar2.setGrip("nasu");
localVar3._setGrip({ "type": "undefined" });
localVar4._setGrip({ "type": "null" });
localVar5._setGrip({ "type": "object", "class": "Object" });
localVar3.setGrip({ "type": "undefined" });
localVar4.setGrip({ "type": "null" });
localVar5.setGrip({ "type": "object", "class": "Object" });
localVar5.addProperties({ "someProp0": { "value": 42, "enumerable": true },
"someProp1": { "value": true , "enumerable": true},
@ -63,10 +63,10 @@ function testSimpleCall() {
"set": { "type": "undefined" },
"enumerable": true } });
windowVar._setGrip({ "type": "object", "class": "Window" });
windowVar.setGrip({ "type": "object", "class": "Window" });
windowVar.addProperties({ "helloWorld": { "value": "hello world" } });
documentVar._setGrip({ "type": "object", "class": "HTMLDocument" });
documentVar.setGrip({ "type": "object", "class": "HTMLDocument" });
documentVar.addProperties({ "onload": { "value": { "type": "null" } },
"onunload": { "value": { "type": "null" } },
"onfocus": { "value": { "type": "null" } },

Просмотреть файл

@ -70,37 +70,20 @@ function testVariablesView()
testThirdLevelContents();
testIntegrity(arr, obj);
gVariablesView.eval = function() {};
gVariablesView.switch = function() {};
gVariablesView.delete = function() {};
let fooScope = gVariablesView.addScope("foo");
let anonymousVar = fooScope.addVar();
let anonymousScope = gVariablesView.addScope();
let barVar = anonymousScope.addVar("bar");
let bazProperty = barVar.addProperty("baz");
is(fooScope.header, true,
"A named scope should have a header visible.");
is(fooScope.target.hasAttribute("non-header"), false,
"The non-header attribute should not be applied to scopes with headers.");
is(anonymousScope.header, false,
"An anonymous scope should have a header visible.");
is(anonymousScope.target.hasAttribute("non-header"), true,
"The non-header attribute should not be applied to scopes without headers.");
is(barVar.header, true,
"A named variable should have a header visible.");
is(barVar.target.hasAttribute("non-header"), false,
"The non-header attribute should not be applied to variables with headers.");
is(anonymousVar.header, false,
"An anonymous variable should have a header visible.");
is(anonymousVar.target.hasAttribute("non-header"), true,
"The non-header attribute should not be applied to variables without headers.");
gVariablesView.clearHierarchy();
is (gVariablesView._prevHierarchy.size, 0,
"The previous hierarchy should have been cleared.");
is (gVariablesView._currHierarchy.size, 0,
"The current hierarchy should have been cleared.");
testAnonymousHeaders(fooScope, anonymousVar, anonymousScope, barVar, bazProperty);
testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar, bazProperty);
testClearHierarchy();
closeDebuggerAndFinish();
}
@ -506,6 +489,107 @@ function testIntegrity(arr, obj) {
is(obj.p6.prop2, 6, "The seventh object property should not have changed");
}
function testAnonymousHeaders(fooScope, anonymousVar, anonymousScope, barVar, bazProperty) {
is(fooScope.header, true,
"A named scope should have a header visible.");
is(fooScope.target.hasAttribute("non-header"), false,
"The non-header attribute should not be applied to scopes with headers.");
is(anonymousScope.header, false,
"An anonymous scope should have a header visible.");
is(anonymousScope.target.hasAttribute("non-header"), true,
"The non-header attribute should not be applied to scopes without headers.");
is(barVar.header, true,
"A named variable should have a header visible.");
is(barVar.target.hasAttribute("non-header"), false,
"The non-header attribute should not be applied to variables with headers.");
is(anonymousVar.header, false,
"An anonymous variable should have a header visible.");
is(anonymousVar.target.hasAttribute("non-header"), true,
"The non-header attribute should not be applied to variables without headers.");
}
function testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar, bazProperty) {
is(fooScope.editableValueTooltip, gVariablesView.editableValueTooltip,
"The editableValueTooltip property should persist from the view to all scopes.");
is(fooScope.editableNameTooltip, gVariablesView.editableNameTooltip,
"The editableNameTooltip property should persist from the view to all scopes.");
is(fooScope.deleteButtonTooltip, gVariablesView.deleteButtonTooltip,
"The deleteButtonTooltip property should persist from the view to all scopes.");
is(fooScope.descriptorTooltip, gVariablesView.descriptorTooltip,
"The descriptorTooltip property should persist from the view to all scopes.");
is(fooScope.contextMenuId, gVariablesView.contextMenuId,
"The contextMenuId property should persist from the view to all scopes.");
is(fooScope.separatorStr, gVariablesView.separatorStr,
"The separatorStr property should persist from the view to all scopes.");
is(fooScope.eval, gVariablesView.eval,
"The eval property should persist from the view to all scopes.");
is(fooScope.switch, gVariablesView.switch,
"The switch property should persist from the view to all scopes.");
is(fooScope.delete, gVariablesView.delete,
"The delete property should persist from the view to all scopes.");
isnot(fooScope.eval, fooScope.switch,
"The eval and switch functions got mixed up in the scope.");
isnot(fooScope.switch, fooScope.delete,
"The eval and switch functions got mixed up in the scope.");
is(barVar.editableValueTooltip, gVariablesView.editableValueTooltip,
"The editableValueTooltip property should persist from the view to all variables.");
is(barVar.editableNameTooltip, gVariablesView.editableNameTooltip,
"The editableNameTooltip property should persist from the view to all variables.");
is(barVar.deleteButtonTooltip, gVariablesView.deleteButtonTooltip,
"The deleteButtonTooltip property should persist from the view to all variables.");
is(barVar.descriptorTooltip, gVariablesView.descriptorTooltip,
"The descriptorTooltip property should persist from the view to all variables.");
is(barVar.contextMenuId, gVariablesView.contextMenuId,
"The contextMenuId property should persist from the view to all variables.");
is(barVar.separatorStr, gVariablesView.separatorStr,
"The separatorStr property should persist from the view to all variables.");
is(barVar.eval, gVariablesView.eval,
"The eval property should persist from the view to all variables.");
is(barVar.switch, gVariablesView.switch,
"The switch property should persist from the view to all variables.");
is(barVar.delete, gVariablesView.delete,
"The delete property should persist from the view to all variables.");
isnot(barVar.eval, barVar.switch,
"The eval and switch functions got mixed up in the variable.");
isnot(barVar.switch, barVar.delete,
"The eval and switch functions got mixed up in the variable.");
is(bazProperty.editableValueTooltip, gVariablesView.editableValueTooltip,
"The editableValueTooltip property should persist from the view to all properties.");
is(bazProperty.editableNameTooltip, gVariablesView.editableNameTooltip,
"The editableNameTooltip property should persist from the view to all properties.");
is(bazProperty.deleteButtonTooltip, gVariablesView.deleteButtonTooltip,
"The deleteButtonTooltip property should persist from the view to all properties.");
is(bazProperty.descriptorTooltip, gVariablesView.descriptorTooltip,
"The descriptorTooltip property should persist from the view to all properties.");
is(bazProperty.contextMenuId, gVariablesView.contextMenuId,
"The contextMenuId property should persist from the view to all properties.");
is(bazProperty.separatorStr, gVariablesView.separatorStr,
"The separatorStr property should persist from the view to all properties.");
is(bazProperty.eval, gVariablesView.eval,
"The eval property should persist from the view to all properties.");
is(bazProperty.switch, gVariablesView.switch,
"The switch property should persist from the view to all properties.");
is(bazProperty.delete, gVariablesView.delete,
"The delete property should persist from the view to all properties.");
isnot(bazProperty.eval, bazProperty.switch,
"The eval and switch functions got mixed up in the property.");
isnot(bazProperty.switch, bazProperty.delete,
"The eval and switch functions got mixed up in the property.");
}
function testClearHierarchy() {
gVariablesView.clearHierarchy();
is (gVariablesView._prevHierarchy.size, 0,
"The previous hierarchy should have been cleared.");
is (gVariablesView._currHierarchy.size, 0,
"The current hierarchy should have been cleared.");
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;

Просмотреть файл

@ -20,6 +20,11 @@ XPCOMUtils.defineLazyModuleGetter(this,
this.EXPORTED_SYMBOLS = ["VariablesView", "create"];
/**
* Debugger localization strings.
*/
const STR = Services.strings.createBundle(DBG_STRINGS_URI);
/**
* A tree view for inspecting scopes, objects and properties.
* Iterable via "for (let [id, scope] in instance) { }".
@ -144,6 +149,97 @@ VariablesView.prototype = {
}.bind(this), aTimeout);
},
/**
* Specifies if this view may be emptied lazily.
* @see VariablesView.prototype.empty
*/
lazyEmpty: false,
/**
* Specifies if nodes in this view may be added lazily.
* @see Scope.prototype._lazyAppend
*/
lazyAppend: true,
/**
* Function called each time a variable or property's value is changed via
* user interaction. If null, then value changes are disabled.
*
* This property is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
eval: null,
/**
* Function called each time a variable or property's name is changed via
* user interaction. If null, then name changes are disabled.
*
* This property is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
switch: null,
/**
* Function called each time a variable or property is deleted via
* user interaction. If null, then deletions are disabled.
*
* This property is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
delete: null,
/**
* The tooltip text shown on a variable or property's value if an |eval|
* function is provided, in order to change the variable or property's value.
*
* This flag is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
editableValueTooltip: STR.GetStringFromName("variablesEditableValueTooltip"),
/**
* The tooltip text shown on a variable or property's name if a |switch|
* function is provided, in order to change the variable or property's name.
*
* This flag is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
editableNameTooltip: STR.GetStringFromName("variablesEditableNameTooltip"),
/**
* The tooltip text shown on a variable or property's delete button if a
* |delete| function is provided, in order to delete the variable or property.
*
* This flag is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
deleteButtonTooltip: STR.GetStringFromName("variablesCloseButtonTooltip"),
/**
* Specifies if the configurable, enumerable or writable tooltip should be
* shown whenever a variable or property descriptor is available.
*
* This flag is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
descriptorTooltip: true,
/**
* Specifies the context menu attribute set on variables and properties.
*
* This flag is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
contextMenuId: "",
/**
* The separator label between the variables or properties name and value.
*
* This flag is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
separatorStr: STR.GetStringFromName("variablesSeparatorLabel"),
/**
* Specifies if enumerable properties and variables should be displayed.
* These variables and properties are visible by default.
@ -477,19 +573,14 @@ VariablesView.prototype = {
_document: null,
_window: null,
eval: null,
switch: null,
delete: null,
lazyEmpty: false,
lazyAppend: true,
_store: null,
_prevHierarchy: null,
_currHierarchy: null,
_enumVisible: true,
_nonEnumVisible: true,
_emptyTimeout: null,
_searchTimeout: null,
_searchFunction: null,
_enumVisible: true,
_nonEnumVisible: true,
_parent: null,
_list: null,
_searchboxNode: null,
@ -511,6 +602,8 @@ VariablesView.prototype = {
* Additional options or flags for this scope.
*/
function Scope(aView, aName, aFlags = {}) {
this.ownerView = aView;
this.expand = this.expand.bind(this);
this.toggle = this.toggle.bind(this);
this._openEnum = this._openEnum.bind(this);
@ -518,10 +611,17 @@ function Scope(aView, aName, aFlags = {}) {
this._batchAppend = this._batchAppend.bind(this);
this._batchItems = [];
this.ownerView = aView;
// Inherit properties and flags from the parent view. You can override
// each of these directly onto any scope, variable or property instance.
this.eval = aView.eval;
this.switch = aView.switch;
this.delete = aView.delete;
this.editableValueTooltip = aView.editableValueTooltip;
this.editableNameTooltip = aView.editableNameTooltip;
this.deleteButtonTooltip = aView.deleteButtonTooltip;
this.descriptorTooltip = aView.descriptorTooltip;
this.contextMenuId = aView.contextMenuId;
this.separatorStr = aView.separatorStr;
this._store = new Map();
this._init(aName.trim(), aFlags);
@ -632,12 +732,12 @@ Scope.prototype = {
// even if they were already displayed before. In this case, show a throbber
// to suggest that this scope is expanding.
if (!this._isExpanding &&
this._store.size > LAZY_APPEND_BATCH && this._variablesView.lazyAppend) {
this._variablesView.lazyAppend && this._store.size > LAZY_APPEND_BATCH) {
this._isExpanding = true;
// Start spinning a throbber in this scope's title.
// Start spinning a throbber in this scope's title and allow a few
// milliseconds for it to be painted.
this._startThrobber();
// Allow the trobber to be painted.
this.window.setTimeout(this.expand, LAZY_EXPAND_DELAY);
return;
}
@ -820,36 +920,6 @@ Scope.prototype = {
this._title.removeEventListener(aName, aCallback, aCapture);
},
/**
* Specifies if the configurable/enumerable/writable tooltip should be shown
* whenever a variable or property descriptor is available.
* This flag applies non-recursively to the current scope.
*/
showDescriptorTooltip: true,
/**
* Specifies if editing variable or property names is allowed.
* This flag applies non-recursively to the current scope.
*/
allowNameInput: false,
/**
* Specifies if editing variable or property values is allowed.
* This flag applies non-recursively to the current scope.
*/
allowValueInput: true,
/**
* Specifies if removing variables or properties values is allowed.
* This flag applies non-recursively to the current scope.
*/
allowDeletion: false,
/**
* Specifies the context menu attribute set on variables and properties.
*/
contextMenu: "",
/**
* Gets the id associated with this item.
* @return string
@ -1041,7 +1111,7 @@ Scope.prototype = {
for (let [, variable] of this._store) {
variable._enumVisible = aFlag;
if (!this.expanded) {
if (!this._isExpanded) {
continue;
}
if (aFlag) {
@ -1060,7 +1130,7 @@ Scope.prototype = {
for (let [, variable] of this._store) {
variable._nonEnumVisible = aFlag;
if (!this.expanded) {
if (!this._isExpanded) {
continue;
}
if (aFlag) {
@ -1185,6 +1255,13 @@ Scope.prototype = {
eval: null,
switch: null,
delete: null,
editableValueTooltip: "",
editableNameTooltip: "",
deleteButtonTooltip: "",
descriptorTooltip: true,
contextMenuId: "",
separatorStr: "",
_store: null,
_fetched: false,
_retrieved: false,
@ -1231,7 +1308,7 @@ function Variable(aScope, aName, aDescriptor) {
this._onValueInputKeyPress = this._onValueInputKeyPress.bind(this);
Scope.call(this, aScope, aName, this._initialDescriptor = aDescriptor);
this._setGrip(aDescriptor.value);
this.setGrip(aDescriptor.value);
this._symbolicName = aName;
this._absoluteName = aScope.name + "[\"" + aName + "\"]";
}
@ -1382,18 +1459,28 @@ create({ constructor: Variable, proto: Scope.prototype }, {
return propertyItem;
},
/**
* Gets this variable's path to the topmost scope.
* For example, a symbolic name may look like "arguments['0']['foo']['bar']".
* @return string
*/
get symbolicName() this._symbolicName,
/**
* Returns this variable's value from the descriptor if available.
* @return any
*/
get value() this._initialDescriptor.value,
/**
* Returns this variable's getter from the descriptor if available.
* @return object
*/
get getter() this._initialDescriptor.get,
/**
* Returns this variable's getter from the descriptor if available.
* @return object
*/
get setter() this._initialDescriptor.set,
@ -1414,7 +1501,7 @@ create({ constructor: Variable, proto: Scope.prototype }, {
* - { type: "null" }
* - { type: "object", class: "Object" }
*/
_setGrip: function V__setGrip(aGrip) {
setGrip: function V_setGrip(aGrip) {
// Don't allow displaying grip information if there's no name available.
if (!this._nameString) {
return;
@ -1489,10 +1576,11 @@ create({ constructor: Variable, proto: Scope.prototype }, {
let separatorLabel = this._separatorLabel = document.createElement("label");
separatorLabel.className = "plain";
separatorLabel.setAttribute("value", this.ownerView.separator);
separatorLabel.setAttribute("value", this.ownerView.separatorStr);
let valueLabel = this._valueLabel = document.createElement("label");
valueLabel.className = "plain value";
valueLabel.setAttribute("crop", "center");
this._title.appendChild(separatorLabel);
this._title.appendChild(valueLabel);
@ -1504,6 +1592,8 @@ create({ constructor: Variable, proto: Scope.prototype }, {
this.hideArrow();
}
if (!isUndefined && (descriptor.get || descriptor.set)) {
// FIXME: editing getters and setters is not allowed yet. Bug 831794.
this.eval = null;
this.addProperty("get", { value: descriptor.get });
this.addProperty("set", { value: descriptor.set });
this.expand();
@ -1516,14 +1606,14 @@ create({ constructor: Variable, proto: Scope.prototype }, {
* Adds specific nodes for this variable based on custom flags.
*/
_customizeVariable: function V__customizeVariable() {
if (this.ownerView.allowDeletion) {
let closeNode = this._closeNode = this.document.createElement("toolbarbutton");
closeNode.className = "plain dbg-variable-delete devtools-closebutton";
closeNode.addEventListener("click", this._onClose.bind(this), false);
this._title.appendChild(closeNode);
if (this.ownerView.delete) {
let deleteNode = this._deleteNode = this.document.createElement("toolbarbutton");
deleteNode.className = "plain dbg-variable-delete devtools-closebutton";
deleteNode.addEventListener("click", this._onDelete.bind(this), false);
this._title.appendChild(deleteNode);
}
if (this.ownerView.contextMenu) {
this._title.setAttribute("context", this.ownerView.contextMenu);
if (this.ownerView.contextMenuId) {
this._title.setAttribute("context", this.ownerView.contextMenuId);
}
},
@ -1540,7 +1630,7 @@ create({ constructor: Variable, proto: Scope.prototype }, {
_displayTooltip: function V__displayTooltip() {
this._target.removeEventListener("mouseover", this._displayTooltip, false);
if (this.ownerView.showDescriptorTooltip) {
if (this.ownerView.descriptorTooltip) {
let document = this.document;
let tooltip = document.createElement("tooltip");
@ -1561,14 +1651,14 @@ create({ constructor: Variable, proto: Scope.prototype }, {
this._target.appendChild(tooltip);
this._target.setAttribute("tooltip", tooltip.id);
}
if (this.ownerView.allowNameInput) {
this._name.setAttribute("tooltiptext", L10N.getStr("variablesEditableNameTooltip"));
if (this.ownerView.eval) {
this._valueLabel.setAttribute("tooltiptext", this.ownerView.editableValueTooltip);
}
if (this.ownerView.allowValueInput) {
this._valueLabel.setAttribute("tooltiptext", L10N.getStr("variablesEditableValueTooltip"));
if (this.ownerView.switch) {
this._name.setAttribute("tooltiptext", this.ownerView.editableNameTooltip);
}
if (this.ownerView.allowDeletion) {
this._closeNode.setAttribute("tooltiptext", L10N.getStr("variablesCloseButtonTooltip"));
if (this.ownerView.delete) {
this._deleteNode.setAttribute("tooltiptext", this.ownerView.deleteButtonTooltip);
}
},
@ -1577,27 +1667,25 @@ create({ constructor: Variable, proto: Scope.prototype }, {
* and specifies if it's a 'this', '<exception>' or '__proto__' reference.
*/
_setAttributes: function V__setAttributes() {
let name = this._nameString;
let descriptor = this._initialDescriptor;
let name = this._nameString;
if (descriptor) {
if (!descriptor.configurable) {
this._target.setAttribute("non-configurable", "");
}
if (!descriptor.enumerable) {
this._target.setAttribute("non-enumerable", "");
}
if (!descriptor.writable) {
this._target.setAttribute("non-writable", "");
}
if (!descriptor.configurable) {
this._target.setAttribute("non-configurable", "");
}
if (!descriptor.enumerable) {
this._target.setAttribute("non-enumerable", "");
}
if (!descriptor.writable) {
this._target.setAttribute("non-writable", "");
}
if (name == "this") {
this._target.setAttribute("self", "");
}
if (name == "<exception>") {
else if (name == "<exception>") {
this._target.setAttribute("exception", "");
}
if (name == "__proto__") {
else if (name == "__proto__") {
this._target.setAttribute("proto", "");
}
},
@ -1683,7 +1771,7 @@ create({ constructor: Variable, proto: Scope.prototype }, {
// Only allow left-click to trigger this event.
return;
}
if (!this.ownerView.allowNameInput || !this.switch) {
if (!this.ownerView.switch) {
return;
}
this._activateInput(this._name, "element-name-input", {
@ -1714,7 +1802,7 @@ create({ constructor: Variable, proto: Scope.prototype }, {
// Only allow left-click to trigger this event.
return;
}
if (!this.ownerView.allowValueInput || !this.eval) {
if (!this.ownerView.eval) {
return;
}
this._activateInput(this._valueLabel, "element-value-input", {
@ -1756,7 +1844,7 @@ create({ constructor: Variable, proto: Scope.prototype }, {
if (initialString != currentString) {
this._disable();
this._name.value = currentString;
this.switch(this, currentString);
this.ownerView.switch(this, currentString);
}
},
@ -1771,7 +1859,7 @@ create({ constructor: Variable, proto: Scope.prototype }, {
if (initialString != currentString) {
this._disable();
this.eval(this._symbolicName + "=" + currentString);
this.ownerView.eval(this._symbolicName + "=" + currentString);
}
},
@ -1806,13 +1894,13 @@ create({ constructor: Variable, proto: Scope.prototype }, {
},
/**
* The click listener for the close button.
* The click listener for the delete button.
*/
_onClose: function V__onClose() {
_onDelete: function V__onDelete() {
this.hide();
if (this.delete) {
this.delete(this);
if (this.ownerView.delete) {
this.ownerView.delete(this);
}
},
@ -1821,7 +1909,7 @@ create({ constructor: Variable, proto: Scope.prototype }, {
_initialDescriptor: null,
_separatorLabel: null,
_valueLabel: null,
_closeNode: null,
_deleteNode: null,
_tooltip: null,
_valueGrip: null,
_valueString: "",
@ -2091,7 +2179,7 @@ VariablesView.getGrip = function VV_getGrip(aValue) {
* Returns a custom formatted property string for a grip.
*
* @param any aGrip
* @see Variable._setGrip
* @see Variable.setGrip
* @param boolean aConciseFlag
* Return a concisely formatted property string.
* @return string
@ -2128,7 +2216,7 @@ VariablesView.getString = function VV_getString(aGrip, aConciseFlag) {
* Returns a custom class style for a grip.
*
* @param any aGrip
* @see Variable._setGrip
* @see Variable.setGrip
* @return string
* The custom class style.
*/
@ -2139,6 +2227,8 @@ VariablesView.getClass = function VV_getClass(aGrip) {
return "token-undefined";
case "null":
return "token-null";
case "longString":
return "token-string";
}
} else {
switch (typeof aGrip) {
@ -2153,31 +2243,6 @@ VariablesView.getClass = function VV_getClass(aGrip) {
return "token-other";
};
/**
* Localization convenience methods.
*/
let L10N = {
/**
* L10N shortcut function.
*
* @param string aName
* @return string
*/
getStr: function L10N_getStr(aName) {
return this.stringBundle.GetStringFromName(aName);
}
};
XPCOMUtils.defineLazyGetter(L10N, "stringBundle", function() {
return Services.strings.createBundle(DBG_STRINGS_URI);
});
/**
* The separator label between the variables or properties name and value.
* This property applies non-recursively to the current scope.
*/
Scope.prototype.separator = L10N.getStr("variablesSeparatorLabel");
/**
* A monotonically-increasing counter, that guarantees the uniqueness of scope,
* variables and properties ids.

Просмотреть файл

@ -303,8 +303,12 @@ tiltCloseDesc=Close the visualization if open
# command, displayed when the user asks for help on what it does.
tiltCloseManual=Close the visualization and switch back to the Inspector's default highlighter
# LOCALIZATION NOTE (debuggerStopped) Used in the output of several commands
# LOCALIZATION NOTE (debuggerClosed) Used in the output of several commands
# to explain that the debugger must be opened first.
debuggerClosed=The debugger must be opened before using this command
# LOCALIZATION NOTE (debuggerStopped) Used in the output of several commands
# to explain that the debugger must be opened first before setting breakpoints.
debuggerStopped=The debugger must be opened before setting breakpoints
# LOCALIZATION NOTE (breakDesc) A very short string used to describe the
@ -420,6 +424,10 @@ dbgStepInDesc=Executes the current statement and then stops at the next statemen
# function of the dbg step out command.
dbgStepOutDesc=Steps out of the current function and up one level if the function is nested. If in the main body, the script is executed to the end, or to the next breakpoint. The skipped statements are executed, but not stepped through
# LOCALIZATION NOTE (dbgListSourcesDesc) A very short string used to describe the
# function of the dbg list command.
dbgListSourcesDesc=List the source URLs loaded in the debugger
# LOCALIZATION NOTE (consolecloseDesc) A very short description of the
# 'console close' 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.

Просмотреть файл

@ -276,8 +276,8 @@
font: 9pt monospace;
}
.dbg-expression-delete {
-moz-image-region: rect(0, 32px, 16px, 16px);
.dbg-expression-delete:not(:hover) {
opacity: 0.5;
}
/**
@ -290,7 +290,6 @@
}
.dbg-variable-delete:not(:hover) {
-moz-image-region: rect(0, 32px, 16px, 16px);
opacity: 0.5;
}
@ -440,6 +439,8 @@
*/
#variables .element-value-input {
overflow: hidden;
max-width: 30em;
-moz-margin-start: 5px !important;
}
@ -484,6 +485,7 @@
}
.token-string {
max-width: 30em;
color: #1c00cf;
}

Просмотреть файл

@ -238,6 +238,9 @@ toolbar[iconsize="large"] > #downloads-indicator[attention] > #downloads-indicat
background-image: url("chrome://browser/skin/downloads/download-glow.png");
}
/* In the next few rules, we use :not([counter]) as a shortcut that is
equivalent to -moz-any([progress], [paused]). */
#downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"),
0, 16, 16, 0) center no-repeat;

Просмотреть файл

@ -282,6 +282,10 @@
-moz-image-region: rect(0, 32px, 16px, 16px);
}
.dbg-expression-delete:not(:hover) {
opacity: 0.5;
}
/**
* Variables view
*/
@ -442,6 +446,8 @@
*/
#variables .element-value-input {
overflow: hidden;
max-width: 30em;
-moz-margin-start: 5px !important;
}
@ -486,6 +492,7 @@
}
.token-string {
max-width: 30em;
color: #1c00cf;
}

Просмотреть файл

@ -376,6 +376,9 @@ richlistitem[type="download"]:hover > stack > .downloadButton.downloadRetry:acti
background-image: url("chrome://browser/skin/downloads/download-glow.png");
}
/* In the next few rules, we use :not([counter]) as a shortcut that is
equivalent to -moz-any([progress], [paused]). */
#downloads-indicator:not([counter])
#downloads-indicator-counter {
background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),

Просмотреть файл

@ -288,6 +288,10 @@
-moz-image-region: rect(0, 32px, 16px, 16px);
}
.dbg-expression-delete:not(:hover) {
opacity: 0.5;
}
/**
* Variables view
*/
@ -448,6 +452,8 @@
*/
#variables .element-value-input {
overflow: hidden;
max-width: 30em;
-moz-margin-start: 5px !important;
}
@ -492,6 +498,7 @@
}
.token-string {
max-width: 30em;
color: #1c00cf;
}

Просмотреть файл

@ -22,11 +22,27 @@
}
@media (-moz-windows-compositor) {
/* The following rules are for the downloads indicator when in its normal,
non-downloading, non-paused state (ie, it's just showing the downloads
button icon). */
#toolbar-menubar #downloads-indicator-icon:not(:-moz-lwtheme),
#TabsToolbar[tabsontop=true] #downloads-indicator-icon:not(:-moz-lwtheme),
#navigator-toolbox[tabsontop=false] > #nav-bar #downloads-indicator-icon:not(:-moz-lwtheme),
#nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child #downloads-indicator-icon:not(:-moz-lwtheme) {
list-style-image: url("chrome://browser/skin/Toolbar-inverted.png");
#nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child #downloads-indicator-icon:not(:-moz-lwtheme),
/* The following rules are for the downloads indicator when in its paused
or undetermined progress state. We use :not([counter]) as a shortcut for
:-moz-any([progress], [paused]). */
/* This is the case where the downloads indicator has been moved next to the menubar */
#toolbar-menubar #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter,
/* This is the case where the downloads indicator is in the tabstrip toolbar with tabs on top. */
#TabsToolbar[tabsontop=true] #downloads-indicator:not(:-moz-lwtheme):not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter,
/* This is the case where the downloads indicator is anywhere in the nav-bar with tabs on bottom. */
#navigator-toolbox[tabsontop=false] > #nav-bar #downloads-indicator:not(:-moz-lwtheme):not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter,
/* This is the case where the downloads indicator is in the tabstrip when the tabstrip is the last item in the toolbox (and is therefore over glass) */
#nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child #downloads-indicator:not(:-moz-lwtheme):not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"), 0, 108, 18, 90);
}
#toolbar-menubar #downloads-indicator-counter:not(:-moz-lwtheme),

Просмотреть файл

@ -257,6 +257,9 @@ richlistitem[type="download"]:hover > stack > .downloadButton.downloadRetry:acti
background-image: url("chrome://browser/skin/downloads/download-glow.png");
}
/* In the next few rules, we use :not([counter]) as a shortcut that is
equivalent to -moz-any([progress], [paused]). */
#downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
0, 108, 18, 90) center no-repeat;

Просмотреть файл

@ -23,10 +23,14 @@ core_abspath = $(if $(filter /%,$(1)),$(1),$(CURDIR)/$(1))
DIST = $(OBJDIR)/dist
postflight_all:
ifdef ENABLE_TESTS
mkdir -p $(DIST_UNI)/$(MOZ_PKG_APPNAME)
rm -f $(DIST_ARCH_2)/universal
ln -s $(call core_abspath,$(DIST_UNI)) $(DIST_ARCH_2)/universal
# Stage a package for buildsymbols to be happy. Doing so in OBJDIR_ARCH_1
# actually does a universal staging with both OBJDIR_ARCH_1 and OBJDIR_ARCH_2.
$(MAKE) -C $(OBJDIR_ARCH_1)/$(INSTALLER_DIR) \
PKG_SKIP_STRIP=1 stage-package
ifdef ENABLE_TESTS
# Now, repeat the process for the test package.
$(MAKE) -C $(OBJDIR_ARCH_1) UNIVERSAL_BINARY= CHROME_JAR= package-tests
$(MAKE) -C $(OBJDIR_ARCH_2) UNIVERSAL_BINARY= CHROME_JAR= package-tests

Просмотреть файл

@ -16,6 +16,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -237,9 +238,10 @@ public class FennecNativeDriver implements Driver {
}
private View getSurfaceView() {
ArrayList<View> views = mSolo.getCurrentViews();
try {
Class c = Class.forName("org.mozilla.gecko.gfx.LayerView");
for (View v : mSolo.getCurrentViews()) {
for (View v : views) {
if (c.isInstance(v)) {
return v;
}
@ -247,6 +249,10 @@ public class FennecNativeDriver implements Driver {
} catch (ClassNotFoundException e) {
log(LogLevel.ERROR, e);
}
log(LogLevel.WARN, "getSurfaceView could not find LayerView");
for (View v : views) {
log(LogLevel.WARN, v.toString());
}
return null;
}

Просмотреть файл

@ -42,11 +42,15 @@ GARBAGE += \
AndroidManifest.xml \
classes.dex \
sutAgentAndroid.apk \
sutAgentAndroid.ap_ \
sutAgentAndroid-unsigned-unaligned.apk \
sutAgentAndroid-unaligned.apk \
$(NULL)
GARBAGE_DIRS += res classes network-libs
GARBAGE_DIRS += network-libs
EXTRA_JARS = $(srcdir)/network-libs/commons-net-2.0.jar:$(srcdir)/network-libs/jmdns.jar
JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar:$(EXTRA_JARS)
include $(topsrcdir)/config/rules.mk
@ -57,26 +61,20 @@ include $(topsrcdir)/config/android-common.mk
tools:: sutAgentAndroid.apk
classes.dex: $(JAVAFILES)
$(NSINSTALL) -D classes
$(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES))
$(DX) --dex --output=$@ classes $(subst :, ,$(EXTRA_JARS))
sutAgentAndroid.ap_: $(srcdir)/AndroidManifest.xml
$(AAPT) package -f -M $(srcdir)/AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -F $@
$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar -S res -F $@
sutAgentAndroid-unsigned-unaligned.apk: sutAgentAndroid.ap_ classes.dex
$(APKBUILDER) $@ -v $(APKBUILDER_FLAGS) -z sutAgentAndroid.ap_ -f classes.dex
sutAgentAndroid-unaligned.apk: sutAgentAndroid-unsigned-unaligned.apk
cp sutAgentAndroid-unsigned-unaligned.apk $@
cp $< $@
ifdef JARSIGNER
$(JARSIGNER) $@
endif
sutAgentAndroid.apk: sutAgentAndroid-unaligned.apk
$(ZIPALIGN) -f -v 4 sutAgentAndroid-unaligned.apk $@
export::
$(NSINSTALL) -D res
@(cd $(srcdir)/res && tar $(TAR_CREATE_FLAGS) - *) | (cd $(DEPTH)/build/mobile/sutagent/android/res && tar -xf -)

Просмотреть файл

@ -33,7 +33,7 @@ GARBAGE += \
FenCP.apk \
$(NULL)
GARBAGE_DIRS += res classes network-libs
GARBAGE_DIRS += network-libs
JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar
@ -45,7 +45,6 @@ include $(topsrcdir)/config/android-common.mk
tools:: FenCP.apk
classes.dex: $(JAVAFILES)
$(NSINSTALL) -D classes
$(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES))
$(DX) --dex --output=$@ classes
@ -63,8 +62,3 @@ endif
FenCP.apk: FenCP-unaligned.apk
$(ZIPALIGN) -f -v 4 FenCP-unaligned.apk $@
export::
$(NSINSTALL) -D res
@(cd $(srcdir)/res && tar $(TAR_CREATE_FLAGS) - *) | (cd $(DEPTH)/build/mobile/sutagent/android/fencp/res && tar -xf -)

Просмотреть файл

@ -33,7 +33,7 @@ GARBAGE += \
FfxCP.apk \
$(NULL)
GARBAGE_DIRS += res classes network-libs
GARBAGE_DIRS += network-libs
JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar
@ -45,7 +45,6 @@ include $(topsrcdir)/config/android-common.mk
tools:: FfxCP.apk
classes.dex: $(JAVAFILES)
$(NSINSTALL) -D classes
$(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES))
$(DX) --dex --output=$@ classes
@ -63,8 +62,3 @@ endif
FfxCP.apk: FfxCP-unaligned.apk
$(ZIPALIGN) -f -v 4 FfxCP-unaligned.apk $@
export::
$(NSINSTALL) -D res
@(cd $(srcdir)/res && tar $(TAR_CREATE_FLAGS) - *) | (cd $(DEPTH)/build/mobile/sutagent/android/ffxcp/res && tar -xf -)

Просмотреть файл

@ -246,6 +246,22 @@
fun:_ZN14nsGlobalWindow22GetComputedStyleHelperEP13nsIDOMElementRK18nsAString_internalbPP25nsIDOMCSSStyleDeclaration
...
}
{
Bug 812423
Memcheck:Leak
fun:malloc
fun:_ZN2js15ArgumentsObject6createI18CopyStackFrameArgsEEPS0_P9JSContextN2JS6HandleIP8JSScriptEENS7_IP10JSFunctionEEjRT_
fun:_ZN2js15ArgumentsObject14createExpectedEP9JSContextPNS_10StackFrameE
...
}
{
Bug 812423
Memcheck:Leak
fun:malloc
fun:_ZN2js15ArgumentsObject6createI13CopyFrameArgsEEPS0_P9JSContextN2JS6HandleIP8JSScriptEENS7_IP10JSFunctionEEjRT_
fun:_ZN2js15ArgumentsObject14createExpectedEP9JSContextNS_16AbstractFramePtrE
...
}
{
Bug 823782
Memcheck:Leak

Просмотреть файл

@ -1,15 +1,4 @@
simplejson.pth:python/simplejson-2.1.1
manifestdestiny.pth:testing/mozbase/manifestdestiny
mozcrash.pth:testing/mozbase/mozcrash
mozdevice.pth:testing/mozbase/mozdevice
mozfile.pth:testing/mozbase/mozfile
mozhttpd.pth:testing/mozbase/mozhttpd
mozinfo.pth:testing/mozbase/mozinfo
mozinstall.pth:testing/mozbase/mozinstall
mozlog.pth:testing/mozbase/mozlog
mozprocess.pth:testing/mozbase/mozprocess
mozprofile.pth:testing/mozbase/mozprofile
mozrunner.pth:testing/mozbase/mozrunner
marionette.pth:testing/marionette/client
blessings.pth:python/blessings
mach.pth:python/mach
@ -23,3 +12,4 @@ mozilla.pth:build
mozilla.pth:config
mozilla.pth:xpcom/typelib/xpt/tools
copy:build/buildconfig.py
packages.txt:testing/mozbase/packages.txt

Просмотреть файл

@ -22,15 +22,17 @@ MINIMUM_PYTHON_MINOR = 7
class VirtualenvManager(object):
"""Contains logic for managing virtualenvs for building the tree."""
def __init__(self, topsrcdir, virtualenv_path, log_handle):
def __init__(self, topsrcdir, virtualenv_path, log_handle, manifest_path):
"""Create a new manager.
Each manager is associated with a source directory, a path where you
want the virtualenv to be created, and a handle to write output to.
"""
assert os.path.isabs(manifest_path), "manifest_path must be an absolute path: %s" % (manifest_path)
self.topsrcdir = topsrcdir
self.virtualenv_root = virtualenv_path
self.log_handle = log_handle
self.manifest_path = manifest_path
@property
def virtualenv_script_path(self):
@ -38,11 +40,6 @@ class VirtualenvManager(object):
return os.path.join(self.topsrcdir, 'python', 'virtualenv',
'virtualenv.py')
@property
def manifest_path(self):
return os.path.join(self.topsrcdir, 'build', 'virtualenv',
'packages.txt')
@property
def python_path(self):
if sys.platform in ('win32', 'cygwin'):
@ -58,6 +55,37 @@ class VirtualenvManager(object):
return os.path.join(self.virtualenv_root, 'bin', 'activate_this.py')
def up_to_date(self):
"""Returns whether the virtualenv is present and up to date."""
deps = [self.manifest_path, __file__]
# check if virtualenv exists
if not os.path.exists(self.virtualenv_root) or \
not os.path.exists(self.activate_path):
return False
# check modification times
activate_mtime = os.path.getmtime(self.activate_path)
dep_mtime = max(os.path.getmtime(p) for p in deps)
if dep_mtime > activate_mtime:
return False
# recursively check sub packages.txt files
submanifests = [i[1] for i in self.packages()
if i[0] == 'packages.txt']
for submanifest in submanifests:
submanifest = os.path.join(self.topsrcdir, submanifest)
submanager = VirtualenvManager(self.topsrcdir,
self.virtualenv_root,
self.log_handle,
submanifest)
if not submanager.up_to_date():
return False
return True
def ensure(self):
"""Ensure the virtualenv is present and up to date.
@ -67,20 +95,9 @@ class VirtualenvManager(object):
This should be the main API used from this class as it is the
highest-level.
"""
deps = [self.manifest_path, __file__]
if not os.path.exists(self.virtualenv_root) or \
not os.path.exists(self.activate_path):
return self.build()
activate_mtime = os.path.getmtime(self.activate_path)
dep_mtime = max(os.path.getmtime(p) for p in deps)
if dep_mtime > activate_mtime:
return self.build()
return self.virtualenv_root
if self.up_to_date():
return self.virtualenv_root
return self.build()
def create(self):
"""Create a new, empty virtualenv.
@ -90,10 +107,7 @@ class VirtualenvManager(object):
write output to.
"""
env = dict(os.environ)
try:
del env['PYTHONDONTWRITEBYTECODE']
except KeyError:
pass
env.pop('PYTHONDONTWRITEBYTECODE', None)
args = [sys.executable, self.virtualenv_script_path,
'--system-site-packages', self.virtualenv_root]
@ -101,11 +115,17 @@ class VirtualenvManager(object):
result = subprocess.call(args, stdout=self.log_handle,
stderr=subprocess.STDOUT, env=env)
if result != 0:
if result:
raise Exception('Error creating virtualenv.')
return self.virtualenv_root
def packages(self):
with file(self.manifest_path, 'rU') as fh:
packages = [line.rstrip().split(':')
for line in fh]
return packages
def populate(self):
"""Populate the virtualenv.
@ -136,11 +156,8 @@ class VirtualenvManager(object):
environment is not configured properly, packages could be installed
into the wrong place. This is how virtualenv's work.
"""
packages = []
fh = open(self.manifest_path, 'rU')
for line in fh:
packages.append(line.rstrip().split(':'))
fh.close()
packages = self.packages()
def handle_package(package):
python_lib = distutils.sysconfig.get_python_lib()
@ -162,6 +179,19 @@ class VirtualenvManager(object):
return True
if package[0] == 'packages.txt':
assert len(package) == 2
src = os.path.join(self.topsrcdir, package[1])
assert os.path.isfile(src), "'%s' does not exist" % src
submanager = VirtualenvManager(self.topsrcdir,
self.virtualenv_root,
self.log_handle,
src)
submanager.populate()
return True
if package[0].endswith('.pth'):
assert len(package) == 2
@ -221,17 +251,12 @@ class VirtualenvManager(object):
for package in packages:
handle_package(package)
finally:
try:
del os.environ['MACOSX_DEPLOYMENT_TARGET']
except KeyError:
pass
os.environ.pop('MACOSX_DEPLOYMENT_TARGET', None)
if old_target is not None:
os.environ['MACOSX_DEPLOYMENT_TARGET'] = old_target
for k in old_env_variables:
os.environ[k] = old_env_variables[k]
os.environ.update(old_env_variables)
def call_setup(self, directory, arguments):
"""Calls setup.py in a directory."""
@ -320,7 +345,10 @@ if __name__ == '__main__':
topsrcdir = sys.argv[2]
virtualenv_path = sys.argv[3]
manager = VirtualenvManager(topsrcdir, virtualenv_path, sys.stdout)
# path to default packages.txt
manifest_path = os.path.join(topsrcdir, 'build', 'virtualenv', 'packages.txt')
manager = VirtualenvManager(topsrcdir, virtualenv_path, sys.stdout, manifest_path)
if populate:
manager.populate()

Просмотреть файл

@ -108,7 +108,7 @@ interface nsIPrincipal : nsISerializable
* principals are not allowed to load anything. This is changed slightly
* by the optional flag allowIfInheritsPrincipal (which defaults to false)
* which allows the load of a data: URI (which inherits the principal of
* its loader) or a URI with the same principal as its loader (eg. a
* its loader) or a URI with the same principal as its loader (eg. a
* Blob URI).
* In these cases, with allowIfInheritsPrincipal set to true, the URI can
* be loaded by a null principal.
@ -159,7 +159,7 @@ interface nsIPrincipal : nsISerializable
* non-hierarchical schemes correctly.
*/
readonly attribute ACString baseDomain;
const short APP_STATUS_NOT_INSTALLED = 0;
const short APP_STATUS_INSTALLED = 1;
const short APP_STATUS_PRIVILEGED = 2;
@ -229,14 +229,14 @@ interface nsIPrincipal : nsISerializable
};
/**
* If nsSystemPrincipal is too risky to use, but we want a principal to access
* more than one origin, nsExpandedPrincipals letting us define an array of
* If nsSystemPrincipal is too risky to use, but we want a principal to access
* more than one origin, nsExpandedPrincipals letting us define an array of
* principals it subsumes. So script with an nsExpandedPrincipals will gain
* same origin access when at least one of its principals it contains gained
* same origin access when at least one of its principals it contains gained
* sameorigin acccess. An nsExpandedPrincipal will be subsumed by the system
* principal, and by another nsExpandedPrincipal that has all its principals.
* It is added for jetpack content-scripts to let them interact with the
* content and a well defined set of other domains, without the risk of
* content and a well defined set of other domains, without the risk of
* leaking out a system principal to the content. See: Bug 734891
*/
[uuid(f3e177Df-6a5e-489f-80a7-2dd1481471d8)]
@ -244,7 +244,7 @@ interface nsIExpandedPrincipal : nsISupports
{
/**
* An array of principals that the expanded principal subsumes.
* Note: this list is not reference counted, it is shared, so
* Note: this list is not reference counted, it is shared, so
* should not be changed and should only be used ephemerally.
*/
[noscript] readonly attribute PrincipalArray whiteList;

Просмотреть файл

@ -440,12 +440,10 @@ private:
// Returns null if a principal cannot be found. Note that rv can be NS_OK
// when this happens -- this means that there was no script associated
// with the function object, and no global object associated with the scope
// of obj (the last object on its parent chain). If the caller is walking
// the JS stack, fp must point to the current frame in the stack iteration.
// Callers MUST pass in a non-null rv here.
// of obj (the last object on its parent chain). Callers MUST pass in a
// non-null rv here.
static nsIPrincipal*
GetFunctionObjectPrincipal(JSContext* cx, JSObject* obj, JSStackFrame *fp,
nsresult* rv);
GetFunctionObjectPrincipal(JSContext* cx, JSObject* obj, nsresult* rv);
/**
* Check capability levels for an |aObj| that implements

Просмотреть файл

@ -1611,7 +1611,7 @@ nsScriptSecurityManager::CheckFunctionAccess(JSContext *aCx, void *aFunObj,
// This check is called for event handlers
nsresult rv;
nsIPrincipal* subject =
GetFunctionObjectPrincipal(aCx, (JSObject *)aFunObj, nullptr, &rv);
GetFunctionObjectPrincipal(aCx, (JSObject *)aFunObj, &rv);
// If subject is null, get a principal from the function object's scope.
if (NS_SUCCEEDED(rv) && !subject)
@ -1971,7 +1971,6 @@ nsScriptSecurityManager::GetScriptPrincipal(JSScript *script,
nsIPrincipal*
nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx,
JSObject *obj,
JSStackFrame *fp,
nsresult *rv)
{
NS_PRECONDITION(rv, "Null out param");
@ -1996,22 +1995,7 @@ nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx,
return nullptr;
}
JSScript *frameScript = fp ? JS_GetFrameScript(cx, fp) : nullptr;
if (frameScript && frameScript != script)
{
// There is a frame script, and it's different from the
// function script. In this case we're dealing with either
// an eval or a Script object, and in these cases the
// principal we want is in the frame's script, not in the
// function's script. The function's script is where the
// eval-calling code came from, not where the eval or new
// Script object came from, and we want the principal of
// the eval function object or new Script object.
script = frameScript;
}
else if (!js::IsOriginalScriptFunction(fun))
if (!js::IsOriginalScriptFunction(fun))
{
// Here, obj is a cloned function object. In this case, the
// clone's prototype may have been precompiled from brutally

Просмотреть файл

@ -286,6 +286,7 @@ CONFIG_STATUS_DEPS := \
$(TOPSRCDIR)/browser/config/version.txt \
$(TOPSRCDIR)/build/virtualenv/packages.txt \
$(TOPSRCDIR)/build/virtualenv/populate_virtualenv.py \
$(TOPSRCDIR)/testing/mozbase/packages.txt \
$(NULL)
CONFIGURE_ENV_ARGS += \

Просмотреть файл

@ -552,6 +552,10 @@ endif
endif
endif
ifdef MACOSX_DEPLOYMENT_TARGET
export MACOSX_DEPLOYMENT_TARGET
endif # MACOSX_DEPLOYMENT_TARGET
ifdef MOZ_USING_CCACHE
ifdef CLANG_CXX
export CCACHE_CPP2=1

Просмотреть файл

@ -0,0 +1,37 @@
# -*- makefile -*-
# vim:set ts=8 sw=8 sts=8 noet:
#
# 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/.
ifndef INCLUDED_JAVA_BUILD_MK #{
ifdef RES_FILES #{
res-dep := .deps-copy-java-res
GENERATED_DIRS += res
GARBAGE += $(res-dep)
export:: $(res-dep)
res-dep-preqs := \
$(addprefix $(srcdir)/,$(RES_FILES)) \
$(call mkdir_deps,res) \
$(if $(IS_LANGUAGE_REPACK),FORCE) \
$(NULL)
# nop-build: only copy res/ files when needed
$(res-dep): $(res-dep-preqs)
$(call copy_dir,$(srcdir)/res,$(CURDIR)/res)
@$(TOUCH) $@
endif #}
ifdef JAVAFILES #{
GENERATED_DIRS += classes
endif #}
INCLUDED_JAVA_BUILD_MK := 1
endif #} INCLUDED_JAVA_BUILD_MK

Просмотреть файл

@ -112,3 +112,6 @@ topORerr =$(if $(topsrcdir),$(topsrcdir),$(error topsrcdir is not defined))
ifdef USE_AUTOTARGETS_MK # mkdir_deps
include $(topORerr)/config/makefiles/autotargets.mk
endif
## copy(src, dst): recursive copy
copy_dir = (cd $(1)/. && $(TAR) $(TAR_CREATE_FLAGS_QUIET) - .) | (cd $(2)/. && tar -xf -)

Просмотреть файл

@ -1100,6 +1100,10 @@ else
normalizepath = $(1)
endif
ifneq (,$(value JAVAFILES)$(value RESFILES))
include $(topsrcdir)/config/makefiles/java-build.mk
endif
_srcdir = $(call normalizepath,$(srcdir))
ifdef JAVA_SOURCEPATH
SP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_SOURCEPATH))))

Просмотреть файл

@ -5213,12 +5213,8 @@ dnl the master list above.
if test -n "$MOZ_WEBRTC"; then
case "$target" in
*-android*|*-linuxandroid*)
if test -n "$MOZ_B2G"; then
MOZ_WEBRTC=1
else
dnl Make sure doesn't get matched by *-linux*
MOZ_WEBRTC=
fi
dnl Make sure doesn't get matched by *-linux*
MOZ_WEBRTC=
;;
*-linux*|*-mingw*|*-darwin*)
dnl Leave enabled
@ -5246,20 +5242,18 @@ if test -n "$MOZ_WEBRTC"; then
MOZ_VP8_ENCODER=1
MOZ_VP8_ERROR_CONCEALMENT=1
if test "$MOZ_WIDGET_TOOLKIT" != "gonk"; then
dnl OpenSLES is only available in Android 2.3 and later; we'll change this
dnl hard dependency to a dynamic load with graceful runtime failure before
dnl we make --enable-webrtc on by default in Android (bug 815905)
dnl
if test "$OS_TARGET" = "Android"; then
LDFLAGS="$LDFLAGS -lOpenSLES"
fi
case "$target" in
*-android*|*-linuxandroid*)
LDFLAGS="$LDFLAGS -lOpenSLES"
;;
esac
dnl OpenSLES is only available in Android 2.3 and later; we'll change this
dnl hard dependency to a dynamic load with graceful runtime failure before
dnl we make --enable-webrtc on by default in Android (bug 815905)
dnl
if test "$OS_TARGET" = "Android"; then
LDFLAGS="$LDFLAGS -lOpenSLES"
fi
case "$target" in
*-android*|*-linuxandroid*)
LDFLAGS="$LDFLAGS -lOpenSLES"
;;
esac
dnl enable once Signaling lands
MOZ_WEBRTC_SIGNALING=1
@ -8993,35 +8987,21 @@ if test "${OS_TARGET}" = "WINNT"; then
EXTRA_GYP_DEFINES="-D MSVS_VERSION=${_MSVS_VERSION} -D MSVS_OS_BITS=${OS_BITS}"
elif test "${OS_TARGET}" = "Android"; then
if test "${MOZ_WIDGET_TOOLKIT}" != "gonk"; then
EXTRA_GYP_DEFINES="-D gtest_target_type=executable -D android_toolchain=${android_toolchain} -G os=android "
fi
EXTRA_GYP_DEFINES="-D gtest_target_type=executable -D android_toolchain=${android_toolchain} -G os=android "
if test -n "$ARM_ARCH" && test "$ARM_ARCH" -lt 7; then
EXTRA_GYP_DEFINES="${EXTRA_GYP_DEFINES} -D armv7=0 "
EXTRA_GYP_DEFINES+=" -D armv7=0 "
else
EXTRA_GYP_DEFINES="${EXTRA_GYP_DEFINES} -D armv7=1 "
EXTRA_GYP_DEFINES+=" -D armv7=1 "
fi
fi
if test -n "$MOZ_WEBRTC"; then
AC_MSG_RESULT("generating WebRTC Makefiles...")
if test "${MOZ_WIDGET_TOOLKIT}" = "gonk"; then
EXTRA_GYP_DEFINES="${EXTRA_GYP_DEFINES} -D moz_widget_toolkit_gonk=1"
else
EXTRA_GYP_DEFINES="${EXTRA_GYP_DEFINES} -D moz_widget_toolkit_gonk=0"
fi
dnl Any --include files must also appear in -D FORCED_INCLUDE_FILE= entries
dnl so that regeneration via dependencies works correctly
WEBRTC_CONFIG="-D build_with_mozilla=1 --include ${srcdir}/media/webrtc/webrtc_config.gypi -D FORCED_INCLUDE_FILE=${srcdir}/media/webrtc/webrtc_config.gypi"
if test -n HAVE_CLOCK_MONOTONIC; then
WEBRTC_CONFIG="${WEBRTC_CONFIG} -D moz_have_clock_monotonic=1"
else
WEBRTC_CONFIG="${WEBRTC_CONFIG} -D moz_have_clock_monotonic=0"
fi
GYP_WEBRTC_OPTIONS="--format=mozmake ${WEBRTC_CONFIG} -D target_arch=${WEBRTC_TARGET_ARCH} ${EXTRA_GYP_DEFINES} --depth=${srcdir}/media/webrtc/trunk --toplevel-dir=${srcdir} -G OBJDIR=${_objdir}"
$PYTHON ${srcdir}/media/webrtc/trunk/build/gyp_chromium \

Просмотреть файл

@ -1,12 +0,0 @@
<html>
<head>
<script type="text/javascript">
try {
document.addBinding(document.documentElement, null);
} catch (e) {
}
</script>
</head>
<body>
</body>
</html>

Просмотреть файл

@ -28,7 +28,6 @@ load 349355-1.html
load 354645-1.xul
load 360599-1.html
load 366200-1.xhtml
load 369216-1.html
load 371466-1.xhtml
load 377360-1.xhtml
load 384663-1.html

Просмотреть файл

@ -95,7 +95,7 @@ interface nsIContentPolicy : nsISupports
/**
* Indicates an XBL binding request, triggered either by -moz-binding CSS
* property or Document.addBinding method.
* property.
*/
const nsContentPolicyType TYPE_XBL = 9;

Просмотреть файл

@ -1946,10 +1946,6 @@ public:
Element* GetAnonymousElementByAttribute(Element& aElement,
const nsAString& aAttrName,
const nsAString& aAttrValue);
void AddBinding(Element& aElement, const nsAString& aURI,
mozilla::ErrorResult& rv);
void RemoveBinding(Element& aElement, const nsAString& aURI,
mozilla::ErrorResult& rv);
Element* GetBindingParent(nsINode& aNode);
void LoadBindingDocument(const nsAString& aURI, mozilla::ErrorResult& rv);
already_AddRefed<nsIDOMXPathExpression>

Просмотреть файл

@ -404,8 +404,7 @@ Element::WrapObject(JSContext *aCx, JSObject *aScope,
}
nsRefPtr<nsXBLBinding> binding;
xblService->LoadBindings(this, uri, principal, false, getter_AddRefs(binding),
&dummy);
xblService->LoadBindings(this, uri, principal, getter_AddRefs(binding), &dummy);
if (binding) {
if (nsContentUtils::IsSafeToRunScript()) {

Просмотреть файл

@ -6360,6 +6360,16 @@ nsContentUtils::FindInternalContentViewer(const char* aType,
}
#endif
#ifdef MOZ_WIDGET_GONK
if (DecoderTraits::IsOmxSupportedType(nsDependentCString(aType))) {
docFactory = do_GetService("@mozilla.org/content/document-loader-factory;1");
if (docFactory && aLoaderType) {
*aLoaderType = TYPE_CONTENT;
}
return docFactory.forget();
}
#endif
#ifdef MOZ_WEBM
if (DecoderTraits::IsWebMType(nsDependentCString(aType))) {
docFactory = do_GetService("@mozilla.org/content/document-loader-factory;1");

Просмотреть файл

@ -5174,77 +5174,6 @@ nsIDocument::ImportNode(nsINode& aNode, bool aDeep, ErrorResult& rv) const
return nullptr;
}
NS_IMETHODIMP
nsDocument::AddBinding(nsIDOMElement* aContent, const nsAString& aURI)
{
nsCOMPtr<Element> element = do_QueryInterface(aContent);
NS_ENSURE_ARG_POINTER(element);
ErrorResult rv;
nsIDocument::AddBinding(*element, aURI, rv);
return rv.ErrorCode();
}
void
nsIDocument::AddBinding(Element& aContent, const nsAString& aURI, ErrorResult& rv)
{
rv = nsContentUtils::CheckSameOrigin(this, &aContent);
if (rv.Failed()) {
return;
}
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), aURI);
if (rv.Failed()) {
return;
}
// Figure out the right principal to use
nsCOMPtr<nsIPrincipal> subject;
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
if (secMan) {
rv = secMan->GetSubjectPrincipal(getter_AddRefs(subject));
if (rv.Failed()) {
return;
}
}
if (!subject) {
// Fall back to our principal. Or should we fall back to the null
// principal? The latter would just mean no binding loads....
subject = NodePrincipal();
}
rv = BindingManager()->AddLayeredBinding(&aContent, uri, subject);
}
NS_IMETHODIMP
nsDocument::RemoveBinding(nsIDOMElement* aContent, const nsAString& aURI)
{
nsCOMPtr<Element> element = do_QueryInterface(aContent);
NS_ENSURE_ARG_POINTER(element);
ErrorResult rv;
nsIDocument::RemoveBinding(*element, aURI, rv);
return rv.ErrorCode();
}
void
nsIDocument::RemoveBinding(Element& aContent, const nsAString& aURI,
ErrorResult& rv)
{
rv = nsContentUtils::CheckSameOrigin(this, &aContent);
if (rv.Failed()) {
return;
}
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), aURI);
if (rv.Failed()) {
return;
}
rv = BindingManager()->RemoveLayeredBinding(&aContent, uri);
}
NS_IMETHODIMP
nsDocument::LoadBindingDocument(const nsAString& aURI)
{

Просмотреть файл

@ -2248,30 +2248,10 @@ nsFrameLoader::DoSendAsyncMessage(const nsAString& aMessage,
PBrowserParent* tabParent = GetRemoteBrowser();
if (tabParent) {
ClonedMessageData data;
SerializedStructuredCloneBuffer& buffer = data.data();
buffer.data = aData.mData;
buffer.dataLength = aData.mDataLength;
const nsTArray<nsCOMPtr<nsIDOMBlob> >& blobs = aData.mClosure.mBlobs;
if (!blobs.IsEmpty()) {
InfallibleTArray<PBlobParent*>& blobParents = data.blobsParent();
uint32_t length = blobs.Length();
blobParents.SetCapacity(length);
ContentParent* cp = static_cast<ContentParent*>(tabParent->Manager());
for (uint32_t i = 0; i < length; ++i) {
BlobParent* blobParent = cp->GetOrCreateActorForBlob(blobs[i]);
if (!blobParent) {
return false;
}
blobParents.AppendElement(blobParent);
}
ContentParent* cp = static_cast<ContentParent*>(tabParent->Manager());
if (!BuildClonedMessageDataForParent(cp, aData, data)) {
return false;
}
return tabParent->SendAsyncMessage(nsString(aMessage), data);
}

Просмотреть файл

@ -119,6 +119,120 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameMessageManager)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameMessageManager)
template<ActorFlavorEnum>
struct DataBlobs
{ };
template<>
struct DataBlobs<Parent>
{
typedef BlobTraits<Parent>::ProtocolType ProtocolType;
static InfallibleTArray<ProtocolType*>& Blobs(ClonedMessageData& aData)
{
return aData.blobsParent();
}
static const InfallibleTArray<ProtocolType*>& Blobs(const ClonedMessageData& aData)
{
return aData.blobsParent();
}
};
template<>
struct DataBlobs<Child>
{
typedef BlobTraits<Child>::ProtocolType ProtocolType;
static InfallibleTArray<ProtocolType*>& Blobs(ClonedMessageData& aData)
{
return aData.blobsChild();
}
static const InfallibleTArray<ProtocolType*>& Blobs(const ClonedMessageData& aData)
{
return aData.blobsChild();
}
};
template<ActorFlavorEnum Flavor>
static bool
BuildClonedMessageData(typename BlobTraits<Flavor>::ConcreteContentManagerType* aManager,
const StructuredCloneData& aData,
ClonedMessageData& aClonedData)
{
SerializedStructuredCloneBuffer& buffer = aClonedData.data();
buffer.data = aData.mData;
buffer.dataLength = aData.mDataLength;
const nsTArray<nsCOMPtr<nsIDOMBlob> >& blobs = aData.mClosure.mBlobs;
if (!blobs.IsEmpty()) {
typedef typename BlobTraits<Flavor>::ProtocolType ProtocolType;
InfallibleTArray<ProtocolType*>& blobList = DataBlobs<Flavor>::Blobs(aClonedData);
uint32_t length = blobs.Length();
blobList.SetCapacity(length);
for (uint32_t i = 0; i < length; ++i) {
Blob<Flavor>* protocolActor = aManager->GetOrCreateActorForBlob(blobs[i]);
if (!protocolActor) {
return false;
}
blobList.AppendElement(protocolActor);
}
}
return true;
}
bool
MessageManagerCallback::BuildClonedMessageDataForParent(ContentParent* aParent,
const StructuredCloneData& aData,
ClonedMessageData& aClonedData)
{
return BuildClonedMessageData<Parent>(aParent, aData, aClonedData);
}
bool
MessageManagerCallback::BuildClonedMessageDataForChild(ContentChild* aChild,
const StructuredCloneData& aData,
ClonedMessageData& aClonedData)
{
return BuildClonedMessageData<Child>(aChild, aData, aClonedData);
}
template<ActorFlavorEnum Flavor>
static StructuredCloneData
UnpackClonedMessageData(const ClonedMessageData& aData)
{
const SerializedStructuredCloneBuffer& buffer = aData.data();
typedef typename BlobTraits<Flavor>::ProtocolType ProtocolType;
const InfallibleTArray<ProtocolType*>& blobs = DataBlobs<Flavor>::Blobs(aData);
StructuredCloneData cloneData;
cloneData.mData = buffer.data;
cloneData.mDataLength = buffer.dataLength;
if (!blobs.IsEmpty()) {
uint32_t length = blobs.Length();
cloneData.mClosure.mBlobs.SetCapacity(length);
for (uint32_t i = 0; i < length; ++i) {
Blob<Flavor>* blob = static_cast<Blob<Flavor>*>(blobs[i]);
MOZ_ASSERT(blob);
nsCOMPtr<nsIDOMBlob> domBlob = blob->GetBlob();
MOZ_ASSERT(domBlob);
cloneData.mClosure.mBlobs.AppendElement(domBlob);
}
}
return cloneData;
}
StructuredCloneData
mozilla::dom::ipc::UnpackClonedMessageDataForParent(const ClonedMessageData& aData)
{
return UnpackClonedMessageData<Parent>(aData);
}
StructuredCloneData
mozilla::dom::ipc::UnpackClonedMessageDataForChild(const ClonedMessageData& aData)
{
return UnpackClonedMessageData<Child>(aData);
}
// nsIMessageListenerManager
NS_IMETHODIMP
@ -1179,21 +1293,8 @@ public:
return true;
}
ClonedMessageData data;
SerializedStructuredCloneBuffer& buffer = data.data();
buffer.data = aData.mData;
buffer.dataLength = aData.mDataLength;
const nsTArray<nsCOMPtr<nsIDOMBlob> >& blobs = aData.mClosure.mBlobs;
if (!blobs.IsEmpty()) {
InfallibleTArray<PBlobChild*>& blobChildList = data.blobsChild();
uint32_t length = blobs.Length();
blobChildList.SetCapacity(length);
for (uint32_t i = 0; i < length; ++i) {
BlobChild* blobChild = cc->GetOrCreateActorForBlob(blobs[i]);
if (!blobChild) {
return false;
}
blobChildList.AppendElement(blobChild);
}
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
return false;
}
return cc->SendSyncMessage(nsString(aMessage), data, aJSONRetVal);
}
@ -1207,21 +1308,8 @@ public:
return true;
}
ClonedMessageData data;
SerializedStructuredCloneBuffer& buffer = data.data();
buffer.data = aData.mData;
buffer.dataLength = aData.mDataLength;
const nsTArray<nsCOMPtr<nsIDOMBlob> >& blobs = aData.mClosure.mBlobs;
if (!blobs.IsEmpty()) {
InfallibleTArray<PBlobChild*>& blobChildList = data.blobsChild();
uint32_t length = blobs.Length();
blobChildList.SetCapacity(length);
for (uint32_t i = 0; i < length; ++i) {
BlobChild* blobChild = cc->GetOrCreateActorForBlob(blobs[i]);
if (!blobChild) {
return false;
}
blobChildList.AppendElement(blobChild);
}
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
return false;
}
return cc->SendAsyncMessage(nsString(aMessage), data);
}

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -26,7 +26,9 @@ namespace mozilla {
namespace dom {
class ContentParent;
class ContentChild;
struct StructuredCloneData;
class ClonedMessageData;
namespace ipc {
@ -76,8 +78,19 @@ public:
{
return false;
}
protected:
bool BuildClonedMessageDataForParent(ContentParent* aParent,
const StructuredCloneData& aData,
ClonedMessageData& aClonedData);
bool BuildClonedMessageDataForChild(ContentChild* aChild,
const StructuredCloneData& aData,
ClonedMessageData& aClonedData);
};
StructuredCloneData UnpackClonedMessageDataForParent(const ClonedMessageData& aData);
StructuredCloneData UnpackClonedMessageDataForChild(const ClonedMessageData& aData);
} // namespace ipc
} // namespace dom
} // namespace mozilla

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше