mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Merge from mozilla-central.
This commit is contained in:
commit
09854d2b71
@ -15,6 +15,10 @@ ifeq ($(OS_ARCH),WINNT)
|
||||
DIRS += $(DEPTH)/xulrunner/tools/redit
|
||||
endif
|
||||
|
||||
ifneq ($(GAIADIR),)
|
||||
DIRS += gaia
|
||||
endif
|
||||
|
||||
DIRS += app
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -16,7 +16,11 @@ DEFINES += -DENABLE_MARIONETTE=1
|
||||
endif
|
||||
|
||||
ifndef LIBXUL_SDK
|
||||
ifneq ($(GAIADIR),)
|
||||
PROGRAM=$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
|
||||
else
|
||||
PROGRAM=$(MOZ_APP_NAME)$(BIN_SUFFIX)
|
||||
endif
|
||||
|
||||
CPPSRCS = nsBrowserApp.cpp
|
||||
|
||||
|
@ -4,75 +4,8 @@
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>html</string>
|
||||
<string>htm</string>
|
||||
<string>shtml</string>
|
||||
<string>xht</string>
|
||||
<string>xhtml</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>document.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>HTML Document</string>
|
||||
<key>CFBundleTypeOSTypes</key>
|
||||
<array>
|
||||
<string>HTML</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>text</string>
|
||||
<string>txt</string>
|
||||
<string>js</string>
|
||||
<string>log</string>
|
||||
<string>css</string>
|
||||
<string>xul</string>
|
||||
<string>rdf</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>document.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Text Document</string>
|
||||
<key>CFBundleTypeOSTypes</key>
|
||||
<array>
|
||||
<string>TEXT</string>
|
||||
<string>utxt</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>jpeg</string>
|
||||
<string>jpg</string>
|
||||
<string>png</string>
|
||||
<string>gif</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>fileBookmark.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>document.icns</string>
|
||||
<key>CFBundleTypeOSTypes</key>
|
||||
<array>
|
||||
<string>GIFf</string>
|
||||
<string>JPEG</string>
|
||||
<string>PNGf</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>%MOZ_APP_NAME%</string>
|
||||
<string>b2g</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>%APP_NAME% %APP_VERSION%</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
@ -89,45 +22,6 @@
|
||||
<string>%APP_VERSION%</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>MOZB</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLIconFile</key>
|
||||
<string>document.icns</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>http URL</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>http</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleURLIconFile</key>
|
||||
<string>document.icns</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>https URL</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>https</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>ftp URL</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>ftp</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>file URL</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>file</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>%APP_VERSION%</string>
|
||||
<key>NSAppleScriptEnabled</key>
|
||||
|
@ -352,8 +352,7 @@ var shell = {
|
||||
this.sendChromeEvent({
|
||||
type: 'open-app',
|
||||
url: msg.uri,
|
||||
origin: origin,
|
||||
manifest: msg.manifest,
|
||||
manifestURL: msg.manifest,
|
||||
isActivity: (msg.type == 'activity'),
|
||||
target: msg.target
|
||||
});
|
||||
@ -601,7 +600,7 @@ var WebappsHelper = {
|
||||
shell.sendChromeEvent({
|
||||
"type": "webapps-launch",
|
||||
"url": manifest.fullLaunchPath(json.startPoint),
|
||||
"origin": json.origin
|
||||
"manifestURL": json.manifestURL
|
||||
});
|
||||
});
|
||||
break;
|
||||
|
42
b2g/gaia/Makefile.in
Normal file
42
b2g/gaia/Makefile.in
Normal file
@ -0,0 +1,42 @@
|
||||
# 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/.
|
||||
|
||||
DEPTH = @DEPTH@
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
GAIA_PATH := gaia/profile
|
||||
|
||||
|
||||
# We don't have a wrapper script on Windows yet
|
||||
ifneq ($(OS_ARCH),WINNT)
|
||||
PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
|
||||
CSRCS = run-b2g.c
|
||||
|
||||
DEFINES += \
|
||||
-DB2G_NAME=\"$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)\" \
|
||||
-DGAIA_PATH=\"$(GAIA_PATH)\" \
|
||||
$(NULL)
|
||||
|
||||
# This is needed to avoid making run-b2g depend on mozglue
|
||||
WRAP_LDFLAGS :=
|
||||
endif
|
||||
|
||||
GENERATED_DIRS += $(DIST)/bin/$(GAIA_PATH)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
||||
libs::
|
||||
# Below here is how Gaia gets built
|
||||
# The Gaia build system freaks out when N > 1 for -jN
|
||||
$(MAKE) -j1 -C $(GAIADIR) clean
|
||||
$(MAKE) -j1 -C $(GAIADIR) profile GAIA_DOMAIN=desktop-builds.$(MOZ_APP_NAME).mozilla.org
|
||||
(cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(abspath $(DIST))/bin/$(GAIA_PATH) && tar -xf -)
|
||||
|
||||
|
||||
|
47
b2g/gaia/run-b2g.c
Normal file
47
b2g/gaia/run-b2g.c
Normal file
@ -0,0 +1,47 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#ifndef B2G_NAME
|
||||
#define B2G_NAME "b2g-bin"
|
||||
#endif
|
||||
#ifndef GAIA_PATH
|
||||
#define GAIA_PATH "gaia/profile"
|
||||
#endif
|
||||
#define NOMEM "Could not allocate enough memory"
|
||||
|
||||
void error(char* msg){
|
||||
fprintf(stderr, "ERROR: %s\n", msg);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[], char* envp[]){
|
||||
char* cwd = NULL;
|
||||
char* full_path = NULL;
|
||||
char* full_profile_path = NULL;
|
||||
printf("Starting %s\n", B2G_NAME);
|
||||
cwd = realpath(dirname(argv[0]), NULL);
|
||||
full_path = (char*) malloc(strlen(cwd) + strlen(B2G_NAME) + 2);
|
||||
if (!full_path) {
|
||||
error(NOMEM);
|
||||
return -2;
|
||||
}
|
||||
full_profile_path = (char*) malloc(strlen(cwd) + strlen(GAIA_PATH) + 2);
|
||||
if (!full_profile_path) {
|
||||
error(NOMEM);
|
||||
return -2;
|
||||
}
|
||||
sprintf(full_path, "%s/%s", cwd, B2G_NAME);
|
||||
sprintf(full_profile_path, "%s/%s", cwd, GAIA_PATH);
|
||||
free(cwd);
|
||||
printf("Running: %s -profile %s\n", full_path, full_profile_path);
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
execle(full_path, full_path, "-profile", full_profile_path, NULL, envp);
|
||||
error("unable to start");
|
||||
perror(argv[0]);
|
||||
free(full_path);
|
||||
free(full_profile_path);
|
||||
return -1;
|
||||
}
|
@ -701,3 +701,9 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
|
||||
#ifdef XP_MACOSX
|
||||
@BINPATH@/@DLL_PREFIX@plugin_child_interpose@DLL_SUFFIX@
|
||||
#endif
|
||||
|
||||
#ifdef PACKAGE_GAIA
|
||||
[gaia]
|
||||
@BINPATH@/gaia/*
|
||||
@BINPATH@/b2g-bin@BIN_SUFFIX@
|
||||
#endif
|
||||
|
@ -89,7 +89,7 @@
|
||||
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
|
||||
<command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>
|
||||
<command id="Tools:DevToolbar" oncommand="DeveloperToolbar.toggle();" disabled="true" hidden="true"/>
|
||||
<command id="Tools:DevToolbarFocus" oncommand="DeveloperToolbar.focus();" disabled="true"/>
|
||||
<command id="Tools:DevToolbarFocus" oncommand="DeveloperToolbar.focusToggle();" disabled="true"/>
|
||||
<command id="Tools:WebConsole" oncommand="HUDConsoleUI.toggleHUD();"/>
|
||||
<command id="Tools:Inspect" oncommand="InspectorUI.toggleInspectorUI();"/>
|
||||
<command id="Tools:Debugger" oncommand="DebuggerUI.toggleDebugger();" disabled="true" hidden="true"/>
|
||||
|
@ -220,6 +220,7 @@ let SocialFlyout = {
|
||||
// create and initialize the panel for this window
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.setAttribute("type", "content");
|
||||
iframe.setAttribute("class", "social-panel-frame");
|
||||
iframe.setAttribute("flex", "1");
|
||||
iframe.setAttribute("origin", Social.provider.origin);
|
||||
panel.appendChild(iframe);
|
||||
@ -536,6 +537,7 @@ var SocialToolbar = {
|
||||
if (!notificationFrame) {
|
||||
notificationFrame = document.createElement("iframe");
|
||||
notificationFrame.setAttribute("type", "content");
|
||||
notificationFrame.setAttribute("class", "social-panel-frame");
|
||||
notificationFrame.setAttribute("id", notificationFrameId);
|
||||
notificationFrame.setAttribute("mozbrowser", "true");
|
||||
notificationFrames.appendChild(notificationFrame);
|
||||
|
@ -658,7 +658,7 @@ var allTabs = {
|
||||
} catch (e) {}
|
||||
tabstring = tab.label + " " + tab.label.toLocaleLowerCase() + " " + tabstring;
|
||||
for (let i = 0; i < filter.length; i++)
|
||||
matches += tabstring.indexOf(filter[i]) > -1;
|
||||
matches += tabstring.contains(filter[i]);
|
||||
}
|
||||
if (matches < filter.length || tab.hidden) {
|
||||
preview.hidden = true;
|
||||
|
@ -1049,7 +1049,7 @@ var gBrowserInit = {
|
||||
|
||||
// set default character set if provided
|
||||
if ("arguments" in window && window.arguments.length > 1 && window.arguments[1]) {
|
||||
if (window.arguments[1].indexOf("charset=") != -1) {
|
||||
if (window.arguments[1].startsWith("charset=")) {
|
||||
var arrayArgComponents = window.arguments[1].split("=");
|
||||
if (arrayArgComponents) {
|
||||
//we should "inherit" the charset menu setting in a new window
|
||||
@ -2758,7 +2758,7 @@ function getMeOutOfHere() {
|
||||
url = prefs.getComplexValue("browser.startup.homepage",
|
||||
Ci.nsIPrefLocalizedString).data;
|
||||
// If url is a pipe-delimited set of pages, just take the first one.
|
||||
if (url.indexOf("|") != -1)
|
||||
if (url.contains("|"))
|
||||
url = url.split("|")[0];
|
||||
} catch(e) {
|
||||
Components.utils.reportError("Couldn't get homepage pref: " + e);
|
||||
@ -3467,7 +3467,7 @@ function FillHistoryMenu(aParent) {
|
||||
|
||||
function addToUrlbarHistory(aUrlToAdd) {
|
||||
if (aUrlToAdd &&
|
||||
aUrlToAdd.indexOf(" ") == -1 &&
|
||||
!aUrlToAdd.contains(" ") &&
|
||||
!/[\x00-\x1F]/.test(aUrlToAdd))
|
||||
PlacesUIUtils.markPageAsTyped(aUrlToAdd);
|
||||
}
|
||||
|
@ -268,10 +268,12 @@
|
||||
</hbox>
|
||||
</panel>
|
||||
|
||||
<panel id="social-notification-panel" type="arrow" hidden="true" noautofocus="true">
|
||||
<panel id="social-notification-panel" class="social-panel"
|
||||
type="arrow" hidden="true" noautofocus="true">
|
||||
<box id="social-notification-box" flex="1"></box>
|
||||
</panel>
|
||||
<panel id="social-flyout-panel"
|
||||
class="social-panel"
|
||||
onpopupshown="SocialFlyout.onShown()"
|
||||
onpopuphidden="SocialFlyout.onHidden()"
|
||||
side="right"
|
||||
|
@ -64,7 +64,7 @@
|
||||
<command id="cmd_pluginsToggle" oncommand="onRadioClick('plugins');"/>
|
||||
</commandset>
|
||||
|
||||
<keyset>
|
||||
<keyset id="pageInfoKeySet">
|
||||
<key key="&closeWindow.key;" modifiers="accel" command="cmd_close"/>
|
||||
<key keycode="VK_ESCAPE" command="cmd_close"/>
|
||||
#ifdef XP_MACOSX
|
||||
@ -102,50 +102,50 @@
|
||||
<!-- General page information -->
|
||||
<vbox id="generalPanel">
|
||||
<textbox class="header" readonly="true" id="titletext"/>
|
||||
<grid>
|
||||
<grid id="generalGrid">
|
||||
<columns>
|
||||
<column/>
|
||||
<column class="gridSeparator"/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<rows id="generalRows">
|
||||
<row id="generalURLRow">
|
||||
<label control="urltext" value="&generalURL;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" id="urltext"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="generalSeparatorRow1">
|
||||
<separator class="thin"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="generalTypeRow">
|
||||
<label control="typetext" value="&generalType;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" id="typetext"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="generalModeRow">
|
||||
<label control="modetext" value="&generalMode;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" crop="end" id="modetext"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="generalEncodingRow">
|
||||
<label control="encodingtext" value="&generalEncoding;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" id="encodingtext"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="generalSizeRow">
|
||||
<label control="sizetext" value="&generalSize;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" id="sizetext"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="generalReferrerRow">
|
||||
<label control="refertext" value="&generalReferrer;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" id="refertext"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="generalSeparatorRow2">
|
||||
<separator class="thin"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="generalModifiedRow">
|
||||
<label control="modifiedtext" value="&generalModified;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" id="modifiedtext"/>
|
||||
@ -165,14 +165,14 @@
|
||||
persist="width" flex="4"
|
||||
onclick="gMetaView.onPageMediaSort('meta-content');"/>
|
||||
</treecols>
|
||||
<treechildren flex="1"/>
|
||||
<treechildren id="metatreechildren" flex="1"/>
|
||||
</tree>
|
||||
</groupbox>
|
||||
<groupbox id="securityBox">
|
||||
<caption id="securityBoxCaption" label="&securityHeader;"/>
|
||||
<description id="general-security-identity" class="header"/>
|
||||
<description id="general-security-privacy" class="header"/>
|
||||
<hbox align="right">
|
||||
<hbox id="securityDetailsButtonBox" align="right">
|
||||
<button id="security-view-details" label="&generalSecurityDetails;"
|
||||
accesskey="&generalSecurityDetails.accesskey;"
|
||||
oncommand="onClickMore();"/>
|
||||
@ -205,7 +205,7 @@
|
||||
width="1" id="image-count" label="&mediaCount;"
|
||||
onclick="gImageView.onPageMediaSort('image-count');"/>
|
||||
</treecols>
|
||||
<treechildren flex="1"/>
|
||||
<treechildren id="imagetreechildren" flex="1"/>
|
||||
</tree>
|
||||
<splitter orient="vertical" id="mediaSplitter"/>
|
||||
<vbox flex="1" id="mediaPreviewBox" collapsed="true">
|
||||
@ -215,51 +215,51 @@
|
||||
<column class="gridSeparator"/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<rows id="mediaRows">
|
||||
<row id="mediaLocationRow">
|
||||
<label control="imageurltext" value="&mediaLocation;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" id="imageurltext"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="mediaTypeRow">
|
||||
<label control="imagetypetext" value="&generalType;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" id="imagetypetext"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="mediaSizeRow">
|
||||
<label control="imagesizetext" value="&generalSize;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" id="imagesizetext"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="mediaDimensionRow">
|
||||
<label control="imagedimensiontext" value="&mediaDimension;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" id="imagedimensiontext"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="mediaTextRow">
|
||||
<label control="imagetext" value="&mediaText;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" id="imagetext"/>
|
||||
</row>
|
||||
<row>
|
||||
<row id="mediaLongdescRow">
|
||||
<label control="imagelongdesctext" value="&mediaLongdesc;"/>
|
||||
<separator/>
|
||||
<textbox readonly="true" id="imagelongdesctext"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<hbox align="end">
|
||||
<vbox>
|
||||
<hbox id="imageSaveBox" align="end">
|
||||
<vbox id="blockImageBox">
|
||||
<checkbox id="blockImage" hidden="true" oncommand="onBlockImage()"
|
||||
accesskey="&mediaBlockImage.accesskey;"/>
|
||||
<label control="thepreviewimage" value="&mediaPreview;" class="header"/>
|
||||
</vbox>
|
||||
<spacer flex="1"/>
|
||||
<spacer id="imageSaveBoxSpacer" flex="1"/>
|
||||
<button label="&mediaSaveAs;" accesskey="&mediaSaveAs.accesskey;"
|
||||
icon="save" id="imagesaveasbutton"
|
||||
oncommand="saveMedia();"/>
|
||||
</hbox>
|
||||
<vbox class="inset iframe" flex="1" pack="center">
|
||||
<vbox id="imagecontainerbox" class="inset iframe" flex="1" pack="center">
|
||||
<hbox id="theimagecontainer" pack="center">
|
||||
<image id="thepreviewimage"/>
|
||||
</hbox>
|
||||
@ -269,9 +269,10 @@
|
||||
</vbox>
|
||||
</vbox>
|
||||
<hbox id="mediaSaveBox" collapsed="true">
|
||||
<spacer flex="1"/>
|
||||
<spacer id="mediaSaveBoxSpacer" flex="1"/>
|
||||
<button label="&mediaSaveAs;" accesskey="&mediaSaveAs2.accesskey;"
|
||||
icon="save" oncommand="saveMedia();"/>
|
||||
icon="save" id="mediasaveasbutton"
|
||||
oncommand="saveMedia();"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
@ -282,17 +283,17 @@
|
||||
|
||||
<!-- Permissions -->
|
||||
<vbox id="permPanel">
|
||||
<hbox>
|
||||
<hbox id="permHostBox">
|
||||
<label value="&permissionsFor;" control="hostText" />
|
||||
<textbox id="hostText" class="header" readonly="true"
|
||||
crop="end" flex="1"/>
|
||||
</hbox>
|
||||
|
||||
<vbox id="permList" flex="1">
|
||||
<vbox class="permission">
|
||||
<vbox class="permission" id="permImageRow">
|
||||
<label class="permissionLabel" id="permImageLabel"
|
||||
value="&permImage;" control="imageRadioGroup"/>
|
||||
<hbox role="group" aria-labelledby="permImageLabel">
|
||||
<hbox id="permImageBox" role="group" aria-labelledby="permImageLabel">
|
||||
<checkbox id="imageDef" command="cmd_imageDef" label="&permUseDefault;"/>
|
||||
<spacer flex="1"/>
|
||||
<radiogroup id="imageRadioGroup" orient="horizontal">
|
||||
@ -301,10 +302,10 @@
|
||||
</radiogroup>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox class="permission">
|
||||
<vbox class="permission" id="permPopupRow">
|
||||
<label class="permissionLabel" id="permPopupLabel"
|
||||
value="&permPopup;" control="popupRadioGroup"/>
|
||||
<hbox role="group" aria-labelledby="permPopupLabel">
|
||||
<hbox id="permPopupBox" role="group" aria-labelledby="permPopupLabel">
|
||||
<checkbox id="popupDef" command="cmd_popupDef" label="&permUseDefault;"/>
|
||||
<spacer flex="1"/>
|
||||
<radiogroup id="popupRadioGroup" orient="horizontal">
|
||||
@ -313,10 +314,10 @@
|
||||
</radiogroup>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox class="permission">
|
||||
<vbox class="permission" id="permCookieRow">
|
||||
<label class="permissionLabel" id="permCookieLabel"
|
||||
value="&permCookie;" control="cookieRadioGroup"/>
|
||||
<hbox role="group" aria-labelledby="permCookieLabel">
|
||||
<hbox id="permCookieBox" role="group" aria-labelledby="permCookieLabel">
|
||||
<checkbox id="cookieDef" command="cmd_cookieDef" label="&permUseDefault;"/>
|
||||
<spacer flex="1"/>
|
||||
<radiogroup id="cookieRadioGroup" orient="horizontal">
|
||||
@ -326,10 +327,10 @@
|
||||
</radiogroup>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox class="permission">
|
||||
<vbox class="permission" id="permInstallRow">
|
||||
<label class="permissionLabel" id="permInstallLabel"
|
||||
value="&permInstall;" control="installRadioGroup"/>
|
||||
<hbox role="group" aria-labelledby="permInstallLabel">
|
||||
<hbox id="permInstallBox" role="group" aria-labelledby="permInstallLabel">
|
||||
<checkbox id="installDef" command="cmd_installDef" label="&permUseDefault;"/>
|
||||
<spacer flex="1"/>
|
||||
<radiogroup id="installRadioGroup" orient="horizontal">
|
||||
@ -338,10 +339,10 @@
|
||||
</radiogroup>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox class="permission">
|
||||
<vbox class="permission" id="permGeoRow" >
|
||||
<label class="permissionLabel" id="permGeoLabel"
|
||||
value="&permGeo;" control="geoRadioGroup"/>
|
||||
<hbox role="group" aria-labelledby="permGeoLabel">
|
||||
<hbox id="permGeoBox" role="group" aria-labelledby="permGeoLabel">
|
||||
<checkbox id="geoDef" command="cmd_geoDef" label="&permAskAlways;"/>
|
||||
<spacer flex="1"/>
|
||||
<radiogroup id="geoRadioGroup" orient="horizontal">
|
||||
@ -350,10 +351,10 @@
|
||||
</radiogroup>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox class="permission">
|
||||
<vbox class="permission" id="permIndexedDBRow">
|
||||
<label class="permissionLabel" id="permIndexedDBLabel"
|
||||
value="&permIndexedDB;" control="indexedDBRadioGroup"/>
|
||||
<hbox role="group" aria-labelledby="permIndexedDBLabel">
|
||||
<hbox id="permIndexedDBBox" role="group" aria-labelledby="permIndexedDBLabel">
|
||||
<checkbox id="indexedDBDef" command="cmd_indexedDBDef" label="&permUseDefault;"/>
|
||||
<spacer flex="1"/>
|
||||
<radiogroup id="indexedDBRadioGroup" orient="horizontal">
|
||||
@ -363,9 +364,9 @@
|
||||
<radio id="indexedDB#2" command="cmd_indexedDBToggle" label="&permBlock;"/>
|
||||
</radiogroup>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<hbox id="permIndexedDBBox2">
|
||||
<spacer flex="1"/>
|
||||
<vbox pack="center">
|
||||
<vbox id="permIndexedDBStatusBox" pack="center">
|
||||
<label id="indexedDBStatus" control="indexedDBClear" hidden="true"/>
|
||||
</vbox>
|
||||
<button id="indexedDBClear" label="&permClearStorage;" hidden="true"
|
||||
@ -375,7 +376,7 @@
|
||||
<vbox class="permission" id="permPluginsRow">
|
||||
<label class="permissionLabel" id="permPluginsLabel"
|
||||
value="&permPlugins;" control="pluginsRadioGroup"/>
|
||||
<hbox role="group" aria-labelledby="permPluginsLabel">
|
||||
<hbox id="permPluginsBox" role="group" aria-labelledby="permPluginsLabel">
|
||||
<checkbox id="pluginsDef" command="cmd_pluginsDef" label="&permAskAlways;"/>
|
||||
<spacer flex="1"/>
|
||||
<radiogroup id="pluginsRadioGroup" orient="horizontal">
|
||||
@ -384,10 +385,10 @@
|
||||
</radiogroup>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox class="permission">
|
||||
<vbox class="permission" id="permFullscreenRow">
|
||||
<label class="permissionLabel" id="permFullscreenLabel"
|
||||
value="&permFullscreen;" control="fullscreenRadioGroup"/>
|
||||
<hbox role="group" aria-labelledby="permFullscreenLabel">
|
||||
<hbox id="permFullscreenBox" role="group" aria-labelledby="permFullscreenLabel">
|
||||
<checkbox id="fullscreenDef" command="cmd_fullscreenDef" label="&permUseDefault;"/>
|
||||
<spacer flex="1"/>
|
||||
<radiogroup id="fullscreenRadioGroup" orient="horizontal">
|
||||
@ -405,13 +406,14 @@
|
||||
<!-- Identity Section -->
|
||||
<groupbox id="security-identity-groupbox" flex="1">
|
||||
<caption id="security-identity" label="&securityView.identity.header;"/>
|
||||
<grid flex="1">
|
||||
<grid id="security-identity-grid" flex="1">
|
||||
<columns>
|
||||
<column/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row><!-- Domain -->
|
||||
<rows id="security-identity-rows">
|
||||
<!-- Domain -->
|
||||
<row id="security-identity-domain-row">
|
||||
<label id="security-identity-domain-label"
|
||||
class="fieldLabel"
|
||||
value="&securityView.identity.domain;"
|
||||
@ -419,7 +421,8 @@
|
||||
<textbox id="security-identity-domain-value"
|
||||
class="fieldValue" readonly="true"/>
|
||||
</row>
|
||||
<row><!-- Owner -->
|
||||
<!-- Owner -->
|
||||
<row id="security-identity-owner-row">
|
||||
<label id="security-identity-owner-label"
|
||||
class="fieldLabel"
|
||||
value="&securityView.identity.owner;"
|
||||
@ -427,7 +430,8 @@
|
||||
<textbox id="security-identity-owner-value"
|
||||
class="fieldValue" readonly="true"/>
|
||||
</row>
|
||||
<row><!-- Verifier -->
|
||||
<!-- Verifier -->
|
||||
<row id="security-identity-verifier-row">
|
||||
<label id="security-identity-verifier-label"
|
||||
class="fieldLabel"
|
||||
value="&securityView.identity.verifier;"
|
||||
@ -438,7 +442,8 @@
|
||||
</rows>
|
||||
</grid>
|
||||
<spacer flex="1"/>
|
||||
<hbox pack="end"><!-- Cert button -->
|
||||
<!-- Cert button -->
|
||||
<hbox id="security-view-cert-box" pack="end">
|
||||
<button id="security-view-cert" label="&securityView.certView;"
|
||||
accesskey="&securityView.accesskey;"
|
||||
oncommand="security.viewCert();"/>
|
||||
@ -448,13 +453,14 @@
|
||||
<!-- Privacy & History section -->
|
||||
<groupbox id="security-privacy-groupbox" flex="1">
|
||||
<caption id="security-privacy" label="&securityView.privacy.header;" />
|
||||
<grid>
|
||||
<grid id="security-privacy-grid">
|
||||
<columns>
|
||||
<column flex="1"/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row><!-- History -->
|
||||
<rows id="security-privacy-rows">
|
||||
<!-- History -->
|
||||
<row id="security-privacy-history-row">
|
||||
<label id="security-privacy-history-label"
|
||||
control="security-privacy-history-value"
|
||||
class="fieldLabel">&securityView.privacy.history;</label>
|
||||
@ -463,11 +469,12 @@
|
||||
value="&securityView.unknown;"
|
||||
readonly="true"/>
|
||||
</row>
|
||||
<row><!-- Cookies -->
|
||||
<!-- Cookies -->
|
||||
<row id="security-privacy-cookies-row">
|
||||
<label id="security-privacy-cookies-label"
|
||||
control="security-privacy-cookies-value"
|
||||
class="fieldLabel">&securityView.privacy.cookies;</label>
|
||||
<hbox align="center">
|
||||
<hbox id="security-privacy-cookies-box" align="center">
|
||||
<textbox id="security-privacy-cookies-value"
|
||||
class="fieldValue"
|
||||
value="&securityView.unknown;"
|
||||
@ -479,11 +486,12 @@
|
||||
oncommand="security.viewCookies();"/>
|
||||
</hbox>
|
||||
</row>
|
||||
<row><!-- Passwords -->
|
||||
<!-- Passwords -->
|
||||
<row id="security-privacy-passwords-row">
|
||||
<label id="security-privacy-passwords-label"
|
||||
control="security-privacy-passwords-value"
|
||||
class="fieldLabel">&securityView.privacy.passwords;</label>
|
||||
<hbox align="center">
|
||||
<hbox id="security-privacy-passwords-box" align="center">
|
||||
<textbox id="security-privacy-passwords-value"
|
||||
class="fieldValue"
|
||||
value="&securityView.unknown;"
|
||||
@ -502,7 +510,7 @@
|
||||
<!-- Technical Details section -->
|
||||
<groupbox id="security-technical-groupbox" flex="1">
|
||||
<caption id="security-technical" label="&securityView.technical.header;" />
|
||||
<vbox flex="1">
|
||||
<vbox id="security-technical-box" flex="1">
|
||||
<label id="security-technical-shortform" class="fieldValue"/>
|
||||
<description id="security-technical-longform1" class="fieldLabel"/>
|
||||
<description id="security-technical-longform2" class="fieldLabel"/>
|
||||
|
@ -7,12 +7,10 @@
|
||||
|
||||
<binding id="chatbox">
|
||||
<content orient="vertical" mousethrough="never">
|
||||
<xul:hbox class="chat-titlebar" xbl:inherits="minimized">
|
||||
<xul:hbox class="chat-titlebar" xbl:inherits="minimized,selected"
|
||||
onclick="document.getBindingParent(this).toggle();">
|
||||
<xul:image class="chat-status-icon" xbl:inherits="src=image"/>
|
||||
<xul:label class="chat-title" flex="1" xbl:inherits="value=label,crop"/>
|
||||
<xul:toolbarbutton class="chat-toggle-button chat-toolbarbutton"
|
||||
xbl:inherits="minimized"
|
||||
oncommand="document.getBindingParent(this).toggle();"/>
|
||||
<xul:toolbarbutton class="chat-close-button chat-toolbarbutton"
|
||||
oncommand="document.getBindingParent(this).close();"/>
|
||||
</xul:hbox>
|
||||
@ -132,7 +130,19 @@
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<field name="selectedChat"/>
|
||||
<property name="selectedChat">
|
||||
<getter><![CDATA[
|
||||
return this._selectedChat;
|
||||
]]></getter>
|
||||
<setter><![CDATA[
|
||||
if (this._selectedChat)
|
||||
this._selectedChat.removeAttribute("selected");
|
||||
this._selectedChat = val;
|
||||
if (val) {
|
||||
this._selectedChat.setAttribute("selected", "true");
|
||||
}
|
||||
]]></setter>
|
||||
</property>
|
||||
|
||||
<field name="menuitemMap">new WeakMap()</field>
|
||||
<field name="chatboxForURL">new Map();</field>
|
||||
|
@ -57,8 +57,8 @@ let RemoteTabViewer = {
|
||||
let item = this._tabsList.getItemAtIndex(i);
|
||||
let hide = false;
|
||||
if (item.getAttribute("type") == "tab") {
|
||||
if (item.getAttribute("url").toLowerCase().indexOf(val) == -1 &&
|
||||
item.getAttribute("title").toLowerCase().indexOf(val) == -1)
|
||||
if (!item.getAttribute("url").toLowerCase().contains(val) &&
|
||||
!item.getAttribute("title").toLowerCase().contains(val))
|
||||
hide = true;
|
||||
else
|
||||
clientTabs++;
|
||||
|
@ -795,7 +795,7 @@
|
||||
// add the scheme and host to the title to prevent spoofing.
|
||||
// XXX https://bugzilla.mozilla.org/show_bug.cgi?id=22183#c239
|
||||
try {
|
||||
if (docElement.getAttribute("chromehidden").indexOf("location") != -1) {
|
||||
if (docElement.getAttribute("chromehidden").contains("location")) {
|
||||
var uri = this.mURIFixup.createExposableURI(
|
||||
aBrowser.currentURI);
|
||||
if (uri.scheme == "about")
|
||||
@ -3750,7 +3750,7 @@
|
||||
} catch (ex) {}
|
||||
|
||||
// valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
|
||||
if (!url || url.indexOf(" ") != -1)
|
||||
if (!url || url.contains(" "))
|
||||
return;
|
||||
|
||||
let bgLoad = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
|
||||
|
@ -19,7 +19,7 @@ function afterZoomAndLoad(aCallback, aTab) {
|
||||
value = undefined;
|
||||
oldAPTS.call(FullZoom, value, browser);
|
||||
// Don't reset _applyPrefToSetting until we've seen the about:blank load(s)
|
||||
if (browser && (browser.currentURI.spec.indexOf("http:") != -1)) {
|
||||
if (browser && browser.currentURI.spec.startsWith("http:")) {
|
||||
FullZoom._applyPrefToSetting = oldAPTS;
|
||||
didZoom = true;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ function test() {
|
||||
executeSoon(function () {
|
||||
let consoleListener = {
|
||||
observe: function (m) {
|
||||
if (m.message.indexOf("NS_ERROR_DOM_BAD_URI") > -1) {
|
||||
if (m.message.contains("NS_ERROR_DOM_BAD_URI")) {
|
||||
ok(true, "drop was blocked");
|
||||
executeSoon(finish);
|
||||
}
|
||||
|
@ -756,7 +756,7 @@ function triggerSecondaryCommand(popup, index) {
|
||||
}, false);
|
||||
|
||||
// One down event to open the popup
|
||||
EventUtils.synthesizeKey("VK_DOWN", { altKey: (navigator.platform.indexOf("Mac") == -1) });
|
||||
EventUtils.synthesizeKey("VK_DOWN", { altKey: !navigator.platform.contains("Mac") });
|
||||
}
|
||||
|
||||
function loadURI(uri, callback) {
|
||||
|
@ -91,6 +91,7 @@ var tests = {
|
||||
}
|
||||
},
|
||||
testWorkerChatWindow: function(next) {
|
||||
const chatUrl = "https://example.com/browser/browser/base/content/test/social_chat.html";
|
||||
let port = Social.provider.port;
|
||||
ok(port, "provider has a port");
|
||||
port.onmessage = function (e) {
|
||||
@ -103,10 +104,11 @@ var tests = {
|
||||
chats.selectedChat.close();
|
||||
}
|
||||
ok(!chats.selectedChat, "chats are all closed");
|
||||
ensureSocialUrlNotRemembered(chatUrl);
|
||||
next();
|
||||
break;
|
||||
}
|
||||
}
|
||||
port.postMessage({topic: "test-worker-chat" });
|
||||
port.postMessage({topic: "test-worker-chat", data: chatUrl});
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ function checkOKButton() {
|
||||
|
||||
// This rest of particular test doesn't really apply on Mac, since buttons
|
||||
// aren't focusable by default.
|
||||
if (navigator.platform.indexOf("Mac") != -1) {
|
||||
if (navigator.platform.contains("Mac")) {
|
||||
executeSoon(testCloseBySpace);
|
||||
return;
|
||||
}
|
||||
@ -151,7 +151,7 @@ function checkOKButton() {
|
||||
let displayName = document.getElementById("socialUserDisplayName");
|
||||
|
||||
// Linux has the buttons in the [unshare] [ok] order, so displayName will come first.
|
||||
if (navigator.platform.indexOf("Linux") != -1) {
|
||||
if (navigator.platform.contains("Linux")) {
|
||||
checkNextInTabOrder(displayName, function () {
|
||||
checkNextInTabOrder(undoButton, function () {
|
||||
checkNextInTabOrder(okButton, testCloseBySpace);
|
||||
|
@ -64,7 +64,7 @@ onconnect = function(e) {
|
||||
testPort.postMessage({topic:"got-flyout-visibility", result: event.data.result});
|
||||
break;
|
||||
case "test-worker-chat":
|
||||
apiPort.postMessage({topic: "social.request-chat", data: "https://example.com/browser/browser/base/content/test/social_chat.html" });
|
||||
apiPort.postMessage({topic: "social.request-chat", data: event.data.data });
|
||||
break;
|
||||
case "social.initialize":
|
||||
// This is the workerAPI port, respond and set up a notification icon.
|
||||
|
@ -76,7 +76,7 @@ function handleMessageEvents(event) {
|
||||
catch (e) {
|
||||
var bodyInnerHTML = "";
|
||||
}
|
||||
if (cacheCount == 2 || (bodyInnerHTML.indexOf("error") != -1)) {
|
||||
if (cacheCount == 2 || bodyInnerHTML.contains("error")) {
|
||||
clearInterval(intervalID);
|
||||
is(cacheCount, 2, "frame not reloaded successfully");
|
||||
if (cacheCount != 2) {
|
||||
|
@ -466,7 +466,7 @@
|
||||
return selectedVal;
|
||||
// The selection doesn't span the full domain if it doesn't contain a slash and is
|
||||
// followed by some character other than a slash.
|
||||
if (selectedVal.indexOf("/") == -1) {
|
||||
if (!selectedVal.contains("/")) {
|
||||
let remainder = inputVal.replace(selectedVal, "");
|
||||
if (remainder != "" && remainder[0] != "/")
|
||||
return selectedVal;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
let EXPORTED_SYMBOLS = ["PageThumbs", "PageThumbsStorage", "PageThumbsCache"];
|
||||
let EXPORTED_SYMBOLS = ["PageThumbs", "PageThumbsStorage"];
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
@ -533,63 +533,3 @@ let PageThumbsHistoryObserver = {
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver])
|
||||
};
|
||||
|
||||
/**
|
||||
* A singleton handling the storage of page thumbnails.
|
||||
*/
|
||||
let PageThumbsCache = {
|
||||
/**
|
||||
* Calls the given callback with a cache entry opened for reading.
|
||||
* @param aKey The key identifying the desired cache entry.
|
||||
* @param aCallback The callback that is called when the cache entry is ready.
|
||||
*/
|
||||
getReadEntry: function Cache_getReadEntry(aKey, aCallback) {
|
||||
// Try to open the desired cache entry.
|
||||
this._openCacheEntry(aKey, Ci.nsICache.ACCESS_READ, aCallback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens the cache entry identified by the given key.
|
||||
* @param aKey The key identifying the desired cache entry.
|
||||
* @param aAccess The desired access mode (see nsICache.ACCESS_* constants).
|
||||
* @param aCallback The function to be called when the cache entry was opened.
|
||||
*/
|
||||
_openCacheEntry: function Cache_openCacheEntry(aKey, aAccess, aCallback) {
|
||||
function onCacheEntryAvailable(aEntry, aAccessGranted, aStatus) {
|
||||
let validAccess = aAccess == aAccessGranted;
|
||||
let validStatus = Components.isSuccessCode(aStatus);
|
||||
|
||||
// Check if a valid entry was passed and if the
|
||||
// access we requested was actually granted.
|
||||
if (aEntry && !(validAccess && validStatus)) {
|
||||
aEntry.close();
|
||||
aEntry = null;
|
||||
}
|
||||
|
||||
aCallback(aEntry);
|
||||
}
|
||||
|
||||
let listener = this._createCacheListener(onCacheEntryAvailable);
|
||||
this._cacheSession.asyncOpenCacheEntry(aKey, aAccess, listener);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a cache listener implementing the nsICacheListener interface.
|
||||
* @param aCallback The callback to be called when the cache entry is available.
|
||||
* @return The new cache listener.
|
||||
*/
|
||||
_createCacheListener: function Cache_createCacheListener(aCallback) {
|
||||
return {
|
||||
onCacheEntryAvailable: aCallback,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICacheListener])
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Define a lazy getter for the cache session.
|
||||
*/
|
||||
XPCOMUtils.defineLazyGetter(PageThumbsCache, "_cacheSession", function () {
|
||||
return Services.cache.createSession(PageThumbs.scheme,
|
||||
Ci.nsICache.STORE_ON_DISK, true);
|
||||
});
|
||||
|
@ -74,13 +74,8 @@ Protocol.prototype = {
|
||||
newChannel: function Proto_newChannel(aURI) {
|
||||
let {url} = parseURI(aURI);
|
||||
let file = PageThumbsStorage.getFileForURL(url);
|
||||
|
||||
if (file.exists()) {
|
||||
let fileuri = Services.io.newFileURI(file);
|
||||
return Services.io.newChannelFromURI(fileuri);
|
||||
}
|
||||
|
||||
return new Channel(aURI);
|
||||
let fileuri = Services.io.newFileURI(file);
|
||||
return Services.io.newChannelFromURI(fileuri);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -95,299 +90,6 @@ Protocol.prototype = {
|
||||
|
||||
let NSGetFactory = XPCOMUtils.generateNSGetFactory([Protocol]);
|
||||
|
||||
/**
|
||||
* A channel implementation responsible for delivering cached thumbnails.
|
||||
*/
|
||||
function Channel(aURI) {
|
||||
this._uri = aURI;
|
||||
|
||||
// nsIChannel
|
||||
this.originalURI = aURI;
|
||||
|
||||
// nsIHttpChannel
|
||||
this._responseHeaders = {"content-type": PageThumbs.contentType};
|
||||
}
|
||||
|
||||
Channel.prototype = {
|
||||
_uri: null,
|
||||
_referrer: null,
|
||||
_canceled: false,
|
||||
_status: Cr.NS_OK,
|
||||
_isPending: false,
|
||||
_wasOpened: false,
|
||||
_responseText: "OK",
|
||||
_responseStatus: 200,
|
||||
_responseHeaders: null,
|
||||
_requestMethod: "GET",
|
||||
_requestStarted: false,
|
||||
_allowPipelining: true,
|
||||
_requestSucceeded: true,
|
||||
|
||||
/* :::::::: nsIChannel ::::::::::::::: */
|
||||
|
||||
get URI() this._uri,
|
||||
owner: null,
|
||||
notificationCallbacks: null,
|
||||
get securityInfo() null,
|
||||
|
||||
contentType: PageThumbs.contentType,
|
||||
contentCharset: null,
|
||||
contentLength: -1,
|
||||
|
||||
get contentDisposition() {
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
},
|
||||
|
||||
get contentDispositionFilename() {
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
},
|
||||
|
||||
get contentDispositionHeader() {
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
},
|
||||
|
||||
open: function Channel_open() {
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_IMPLEMENTED);
|
||||
},
|
||||
|
||||
asyncOpen: function Channel_asyncOpen(aListener, aContext) {
|
||||
if (this._isPending)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
|
||||
|
||||
if (this._wasOpened)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_ALREADY_OPENED);
|
||||
|
||||
if (this._canceled)
|
||||
return (Components.returnCode = this._status);
|
||||
|
||||
this._isPending = true;
|
||||
this._wasOpened = true;
|
||||
|
||||
this._listener = aListener;
|
||||
this._context = aContext;
|
||||
|
||||
if (this.loadGroup)
|
||||
this.loadGroup.addRequest(this, null);
|
||||
|
||||
if (this._canceled)
|
||||
return;
|
||||
|
||||
let {url} = parseURI(this._uri);
|
||||
if (!url) {
|
||||
this._serveThumbnailNotFound();
|
||||
return;
|
||||
}
|
||||
|
||||
PageThumbsCache.getReadEntry(url, function (aEntry) {
|
||||
let inputStream = aEntry && aEntry.openInputStream(0);
|
||||
if (!inputStream || !inputStream.available()) {
|
||||
if (aEntry)
|
||||
aEntry.close();
|
||||
this._serveThumbnailNotFound();
|
||||
return;
|
||||
}
|
||||
|
||||
this._entry = aEntry;
|
||||
this._pump = Cc["@mozilla.org/network/input-stream-pump;1"].
|
||||
createInstance(Ci.nsIInputStreamPump);
|
||||
|
||||
this._pump.init(inputStream, -1, -1, 0, 0, true);
|
||||
this._pump.asyncRead(this, null);
|
||||
|
||||
this._trackThumbnailHitOrMiss(true);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Serves a "404 Not Found" if we didn't find the requested thumbnail.
|
||||
*/
|
||||
_serveThumbnailNotFound: function Channel_serveThumbnailNotFound() {
|
||||
this._responseStatus = 404;
|
||||
this._responseText = "Not Found";
|
||||
this._requestSucceeded = false;
|
||||
|
||||
this.onStartRequest(this, null);
|
||||
this.onStopRequest(this, null, Cr.NS_OK);
|
||||
|
||||
this._trackThumbnailHitOrMiss(false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements telemetry tracking for thumbnail cache hits and misses.
|
||||
* @param aFound Whether the thumbnail was found.
|
||||
*/
|
||||
_trackThumbnailHitOrMiss: function Channel_trackThumbnailHitOrMiss(aFound) {
|
||||
Services.telemetry.getHistogramById("FX_THUMBNAILS_HIT_OR_MISS")
|
||||
.add(aFound);
|
||||
},
|
||||
|
||||
/* :::::::: nsIStreamListener ::::::::::::::: */
|
||||
|
||||
onStartRequest: function Channel_onStartRequest(aRequest, aContext) {
|
||||
if (!this.canceled && Components.isSuccessCode(this._status))
|
||||
this._status = aRequest.status;
|
||||
|
||||
this._requestStarted = true;
|
||||
this._listener.onStartRequest(this, this._context);
|
||||
},
|
||||
|
||||
onDataAvailable: function Channel_onDataAvailable(aRequest, aContext,
|
||||
aInStream, aOffset, aCount) {
|
||||
this._listener.onDataAvailable(this, this._context, aInStream, aOffset, aCount);
|
||||
},
|
||||
|
||||
onStopRequest: function Channel_onStopRequest(aRequest, aContext, aStatus) {
|
||||
this._isPending = false;
|
||||
this._status = aStatus;
|
||||
|
||||
this._listener.onStopRequest(this, this._context, aStatus);
|
||||
this._listener = null;
|
||||
this._context = null;
|
||||
|
||||
if (this._entry)
|
||||
this._entry.close();
|
||||
|
||||
if (this.loadGroup)
|
||||
this.loadGroup.removeRequest(this, null, aStatus);
|
||||
},
|
||||
|
||||
/* :::::::: nsIRequest ::::::::::::::: */
|
||||
|
||||
get status() this._status,
|
||||
get name() this._uri.spec,
|
||||
isPending: function Channel_isPending() this._isPending,
|
||||
|
||||
loadFlags: Ci.nsIRequest.LOAD_NORMAL,
|
||||
loadGroup: null,
|
||||
|
||||
cancel: function Channel_cancel(aStatus) {
|
||||
if (this._canceled)
|
||||
return;
|
||||
|
||||
this._canceled = true;
|
||||
this._status = aStatus;
|
||||
|
||||
if (this._pump)
|
||||
this._pump.cancel(aStatus);
|
||||
},
|
||||
|
||||
suspend: function Channel_suspend() {
|
||||
if (this._pump)
|
||||
this._pump.suspend();
|
||||
},
|
||||
|
||||
resume: function Channel_resume() {
|
||||
if (this._pump)
|
||||
this._pump.resume();
|
||||
},
|
||||
|
||||
/* :::::::: nsIHttpChannel ::::::::::::::: */
|
||||
|
||||
get referrer() this._referrer,
|
||||
|
||||
set referrer(aReferrer) {
|
||||
if (this._wasOpened)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
|
||||
|
||||
this._referrer = aReferrer;
|
||||
},
|
||||
|
||||
get requestMethod() this._requestMethod,
|
||||
|
||||
set requestMethod(aMethod) {
|
||||
if (this._wasOpened)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
|
||||
|
||||
this._requestMethod = aMethod.toUpperCase();
|
||||
},
|
||||
|
||||
get allowPipelining() this._allowPipelining,
|
||||
|
||||
set allowPipelining(aAllow) {
|
||||
if (this._wasOpened)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_FAILURE);
|
||||
|
||||
this._allowPipelining = aAllow;
|
||||
},
|
||||
|
||||
redirectionLimit: 10,
|
||||
|
||||
get responseStatus() {
|
||||
if (this._requestStarted)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
return this._responseStatus;
|
||||
},
|
||||
|
||||
get responseStatusText() {
|
||||
if (this._requestStarted)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
return this._responseText;
|
||||
},
|
||||
|
||||
get requestSucceeded() {
|
||||
if (this._requestStarted)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
return this._requestSucceeded;
|
||||
},
|
||||
|
||||
isNoCacheResponse: function Channel_isNoCacheResponse() false,
|
||||
isNoStoreResponse: function Channel_isNoStoreResponse() false,
|
||||
|
||||
getRequestHeader: function Channel_getRequestHeader() {
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
},
|
||||
|
||||
setRequestHeader: function Channel_setRequestHeader() {
|
||||
if (this._wasOpened)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
|
||||
},
|
||||
|
||||
visitRequestHeaders: function Channel_visitRequestHeaders() {},
|
||||
|
||||
getResponseHeader: function Channel_getResponseHeader(aHeader) {
|
||||
let name = aHeader.toLowerCase();
|
||||
if (name in this._responseHeaders)
|
||||
return this._responseHeaders[name];
|
||||
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
},
|
||||
|
||||
setResponseHeader: function Channel_setResponseHeader(aHeader, aValue, aMerge) {
|
||||
let name = aHeader.toLowerCase();
|
||||
if (!aValue && !aMerge)
|
||||
delete this._responseHeaders[name];
|
||||
else
|
||||
this._responseHeaders[name] = aValue;
|
||||
},
|
||||
|
||||
visitResponseHeaders: function Channel_visitResponseHeaders(aVisitor) {
|
||||
for (let name in this._responseHeaders) {
|
||||
let value = this._responseHeaders[name];
|
||||
|
||||
try {
|
||||
aVisitor.visitHeader(name, value);
|
||||
} catch (e) {
|
||||
// The visitor can throw to stop the iteration.
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/* :::::::: nsIHttpChannelInternal ::::::::::::::: */
|
||||
|
||||
documentURI: null,
|
||||
get canceled() this._canceled,
|
||||
allowSpdy: false,
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel,
|
||||
Ci.nsIHttpChannel,
|
||||
Ci.nsIHttpChannelInternal,
|
||||
Ci.nsIRequest])
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a given URI and extracts all parameters relevant to this protocol.
|
||||
* @param aURI The URI to parse.
|
||||
|
@ -41,7 +41,7 @@ gcli.addCommand({
|
||||
manual: gcli.lookup("screenshotFullPageManual")
|
||||
},
|
||||
{
|
||||
name: "node",
|
||||
name: "selector",
|
||||
type: "node",
|
||||
defaultValue: null,
|
||||
description: gcli.lookup("inspectNodeDesc"),
|
||||
@ -59,7 +59,7 @@ gcli.addCommand({
|
||||
return promise;
|
||||
}
|
||||
else {
|
||||
return this.grabScreen(document, args.filename, args.fullpage, args.node);
|
||||
return this.grabScreen(document, args.filename, args.fullpage, args.selector);
|
||||
}
|
||||
},
|
||||
grabScreen:
|
||||
|
@ -1707,7 +1707,7 @@ var types = require('gcli/types');
|
||||
var Type = require('gcli/types').Type;
|
||||
var Status = require('gcli/types').Status;
|
||||
var Conversion = require('gcli/types').Conversion;
|
||||
var Speller = require('gcli/types/spell').Speller;
|
||||
var spell = require('gcli/types/spell');
|
||||
|
||||
|
||||
/**
|
||||
@ -1888,13 +1888,14 @@ SelectionType.prototype._findPredictions = function(arg) {
|
||||
}
|
||||
|
||||
// Try fuzzy matching if we don't get a prefix match
|
||||
if (false && predictions.length === 0) {
|
||||
var speller = new Speller();
|
||||
var names = lookup.map(function(opt) {
|
||||
return opt.name;
|
||||
if (predictions.length === 0) {
|
||||
var names = [];
|
||||
lookup.forEach(function(opt) {
|
||||
if (!opt.value.hidden) {
|
||||
names.push(opt.name);
|
||||
}
|
||||
});
|
||||
speller.train(names);
|
||||
var corrected = speller.correct(match);
|
||||
var corrected = spell.correct(match, names);
|
||||
if (corrected) {
|
||||
lookup.forEach(function(opt) {
|
||||
if (opt.name === corrected) {
|
||||
@ -2005,154 +2006,117 @@ exports.SelectionType = SelectionType;
|
||||
|
||||
});
|
||||
/*
|
||||
* Copyright (c) 2009 Panagiotis Astithas
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
* Copyright 2012, Mozilla Foundation and contributors
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
define('gcli/types/spell', ['require', 'exports', 'module' ], function(require, exports, module) {
|
||||
|
||||
/*
|
||||
* A spell-checker based on Damerau-Levenshtein distance.
|
||||
*/
|
||||
|
||||
var INSERTION_COST = 1;
|
||||
var DELETION_COST = 1;
|
||||
var SWAP_COST = 1;
|
||||
var SUBSTITUTION_COST = 2;
|
||||
var MAX_EDIT_DISTANCE = 4;
|
||||
|
||||
/**
|
||||
* A spell-checker based on the statistical algorithm described by Peter Norvig
|
||||
* in http://norvig.com/spell-correct.html, and converted to JavaScript by Past
|
||||
* http://past.github.com/speller/
|
||||
*
|
||||
* Usage requires a two-step process:
|
||||
* 1) call speller.train() one or more times with a large text to train the
|
||||
* language model
|
||||
* 2) call speller.correct(word) to retrieve the correction for the specified
|
||||
* word
|
||||
* Compute Damerau-Levenshtein Distance
|
||||
* @see http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
|
||||
*/
|
||||
function Speller() {
|
||||
// A map of words to the count of times they were encountered during training.
|
||||
this._nWords = {};
|
||||
}
|
||||
function damerauLevenshteinDistance(wordi, wordj) {
|
||||
var N = wordi.length;
|
||||
var M = wordj.length;
|
||||
|
||||
Speller.letters = "abcdefghijklmnopqrstuvwxyz".split("");
|
||||
// We only need to store three rows of our dynamic programming matrix.
|
||||
// (Without swap, it would have been two.)
|
||||
var row0 = new Array(N+1);
|
||||
var row1 = new Array(N+1);
|
||||
var row2 = new Array(N+1);
|
||||
var tmp;
|
||||
|
||||
/**
|
||||
* A function that trains the language model with the words in the supplied
|
||||
* text. Multiple invocation of this function can extend the training of the
|
||||
* model.
|
||||
*/
|
||||
Speller.prototype.train = function(words) {
|
||||
words.forEach(function(word) {
|
||||
word = word.toLowerCase();
|
||||
this._nWords[word] = this._nWords.hasOwnProperty(word) ?
|
||||
this._nWords[word] + 1 :
|
||||
1;
|
||||
}, this);
|
||||
var i, j;
|
||||
|
||||
// The distance between the empty string and a string of size i is the cost
|
||||
// of i insertions.
|
||||
for (i = 0; i <= N; i++) {
|
||||
row1[i] = i * INSERTION_COST;
|
||||
}
|
||||
|
||||
// Row-by-row, we're computing the edit distance between substrings wordi[0..i]
|
||||
// and wordj[0..j].
|
||||
for (j = 1; j <= M; j++)
|
||||
{
|
||||
// Edit distance between wordi[0..0] and wordj[0..j] is the cost of j
|
||||
// insertions.
|
||||
row0[0] = j * INSERTION_COST;
|
||||
|
||||
for (i = 1; i <= N; i++)
|
||||
{
|
||||
// Handle deletion, insertion and substitution: we can reach each cell
|
||||
// from three other cells corresponding to those three operations. We
|
||||
// want the minimum cost.
|
||||
row0[i] = Math.min(
|
||||
row0[i-1] + DELETION_COST,
|
||||
row1[i] + INSERTION_COST,
|
||||
row1[i-1] + (wordi[i-1] === wordj[j-1] ? 0 : SUBSTITUTION_COST));
|
||||
// We handle swap too, eg. distance between help and hlep should be 1. If
|
||||
// we find such a swap, there's a chance to update row0[1] to be lower.
|
||||
if (i > 1 && j > 1 && wordi[i-1] === wordj[j-2] && wordj[j-1] === wordi[i-2]) {
|
||||
row0[i] = Math.min(row0[i], row2[i-2] + SWAP_COST);
|
||||
}
|
||||
}
|
||||
|
||||
tmp = row2;
|
||||
row2 = row1;
|
||||
row1 = row0;
|
||||
row0 = tmp;
|
||||
}
|
||||
|
||||
return row1[N];
|
||||
};
|
||||
|
||||
/**
|
||||
* A function that returns the correction for the specified word.
|
||||
*/
|
||||
Speller.prototype.correct = function(word) {
|
||||
if (this._nWords.hasOwnProperty(word)) {
|
||||
return word;
|
||||
}
|
||||
exports.correct = function(word, names) {
|
||||
var distance = {};
|
||||
var sorted_candidates;
|
||||
|
||||
var candidates = {};
|
||||
var list = this._edits(word);
|
||||
list.forEach(function(edit) {
|
||||
if (this._nWords.hasOwnProperty(edit)) {
|
||||
candidates[this._nWords[edit]] = edit;
|
||||
names.forEach(function(candidate) {
|
||||
distance[candidate] = damerauLevenshteinDistance(word, candidate);
|
||||
});
|
||||
|
||||
sorted_candidates = names.sort(function(worda, wordb) {
|
||||
if (distance[worda] !== distance[wordb]) {
|
||||
return distance[worda] - distance[wordb];
|
||||
} else {
|
||||
// if the score is the same, always return the first string
|
||||
// in the lexicographical order
|
||||
return worda < wordb;
|
||||
}
|
||||
}, this);
|
||||
});
|
||||
|
||||
if (this._countKeys(candidates) > 0) {
|
||||
return candidates[this._max(candidates)];
|
||||
if (distance[sorted_candidates[0]] <= MAX_EDIT_DISTANCE) {
|
||||
return sorted_candidates[0];
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
list.forEach(function(edit) {
|
||||
this._edits(edit).forEach(function(w) {
|
||||
if (this._nWords.hasOwnProperty(w)) {
|
||||
candidates[this._nWords[w]] = w;
|
||||
}
|
||||
}, this);
|
||||
}, this);
|
||||
|
||||
return this._countKeys(candidates) > 0 ?
|
||||
candidates[this._max(candidates)] :
|
||||
null;
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper function that counts the keys in the supplied object.
|
||||
*/
|
||||
Speller.prototype._countKeys = function(object) {
|
||||
// return Object.keys(object).length; ?
|
||||
var count = 0;
|
||||
for (var attr in object) {
|
||||
if (object.hasOwnProperty(attr)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper function that returns the word with the most occurrences in the
|
||||
* language model, among the supplied candidates.
|
||||
* @param candidates
|
||||
*/
|
||||
Speller.prototype._max = function(candidates) {
|
||||
var arr = [];
|
||||
for (var candidate in candidates) {
|
||||
if (candidates.hasOwnProperty(candidate)) {
|
||||
arr.push(candidate);
|
||||
}
|
||||
}
|
||||
return Math.max.apply(null, arr);
|
||||
};
|
||||
|
||||
/**
|
||||
* A function that returns the set of possible corrections of the specified
|
||||
* word. The edits can be deletions, insertions, alterations or transpositions.
|
||||
*/
|
||||
Speller.prototype._edits = function(word) {
|
||||
var results = [];
|
||||
|
||||
// Deletion
|
||||
for (var i = 0; i < word.length; i++) {
|
||||
results.push(word.slice(0, i) + word.slice(i + 1));
|
||||
}
|
||||
|
||||
// Transposition
|
||||
for (i = 0; i < word.length - 1; i++) {
|
||||
results.push(word.slice(0, i) + word.slice(i + 1, i + 2)
|
||||
+ word.slice(i, i + 1) + word.slice(i + 2));
|
||||
}
|
||||
|
||||
// Alteration
|
||||
for (i = 0; i < word.length; i++) {
|
||||
Speller.letters.forEach(function(l) {
|
||||
results.push(word.slice(0, i) + l + word.slice(i + 1));
|
||||
}, this);
|
||||
}
|
||||
|
||||
// Insertion
|
||||
for (i = 0; i <= word.length; i++) {
|
||||
Speller.letters.forEach(function(l) {
|
||||
results.push(word.slice(0, i) + l + word.slice(i));
|
||||
}, this);
|
||||
}
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.Speller = Speller;
|
||||
|
||||
|
||||
});
|
||||
/*
|
||||
@ -4068,7 +4032,9 @@ exports._empty = [];
|
||||
*/
|
||||
exports.setDocument = function(document) {
|
||||
doc = document;
|
||||
exports._empty = doc.querySelectorAll('x>:root');
|
||||
if (doc != null) {
|
||||
exports._empty = doc.querySelectorAll('x>:root');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -5127,7 +5093,7 @@ var view = require('gcli/ui/view');
|
||||
var l10n = require('gcli/l10n');
|
||||
|
||||
var canon = require('gcli/canon');
|
||||
var Promise = require('gcli/promise').Promise;
|
||||
var Q = require('gcli/promise');
|
||||
|
||||
var Status = require('gcli/types').Status;
|
||||
var Conversion = require('gcli/types').Conversion;
|
||||
@ -5190,8 +5156,6 @@ function Assignment(param, paramIndex) {
|
||||
this.paramIndex = paramIndex;
|
||||
|
||||
this.onAssignmentChange = util.createEvent('Assignment.onAssignmentChange');
|
||||
|
||||
this.setBlank();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5275,39 +5239,6 @@ Assignment.prototype.isInName = function() {
|
||||
this.conversion.arg.prefix.slice(-1) !== ' ';
|
||||
};
|
||||
|
||||
/**
|
||||
* Report on the status of the last parse() conversion.
|
||||
* We force mutations to happen through this method rather than have
|
||||
* setValue and setArgument functions to help maintain integrity when we
|
||||
* have ArrayArguments and don't want to get confused. This way assignments
|
||||
* are just containers for a conversion rather than things that store
|
||||
* a connection between an arg/value.
|
||||
* @see types.Conversion
|
||||
*/
|
||||
Assignment.prototype.setConversion = function(conversion) {
|
||||
var oldConversion = this.conversion;
|
||||
|
||||
this.conversion = conversion;
|
||||
this.conversion.assign(this);
|
||||
|
||||
if (this.conversion.equals(oldConversion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.onAssignmentChange({
|
||||
assignment: this,
|
||||
conversion: this.conversion,
|
||||
oldConversion: oldConversion
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup an empty value for the conversion by parsing an empty argument.
|
||||
*/
|
||||
Assignment.prototype.setBlank = function() {
|
||||
this.setConversion(this.param.type.getBlank());
|
||||
};
|
||||
|
||||
/**
|
||||
* Make sure that there is some content for this argument by using an
|
||||
* Argument of '' if needed.
|
||||
@ -5454,8 +5385,6 @@ function CommandAssignment() {
|
||||
this.param = new canon.Parameter(commandParamMetadata);
|
||||
this.paramIndex = -1;
|
||||
this.onAssignmentChange = util.createEvent('CommandAssignment.onAssignmentChange');
|
||||
|
||||
this.setBlank();
|
||||
}
|
||||
|
||||
CommandAssignment.prototype = Object.create(Assignment.prototype);
|
||||
@ -5540,6 +5469,7 @@ function Requisition(environment, doc) {
|
||||
// The command that we are about to execute.
|
||||
// @see setCommandConversion()
|
||||
this.commandAssignment = new CommandAssignment();
|
||||
this._setAssignment(this.commandAssignment, null, true);
|
||||
|
||||
// The object that stores of Assignment objects that we are filling out.
|
||||
// The Assignment objects are stored under their param.name for named
|
||||
@ -5626,6 +5556,7 @@ Requisition.prototype._commandAssignmentChanged = function(ev) {
|
||||
for (var i = 0; i < command.params.length; i++) {
|
||||
var param = command.params[i];
|
||||
var assignment = new Assignment(param, i);
|
||||
this._setAssignment(assignment, null, true);
|
||||
assignment.onAssignmentChange.add(this._assignmentChanged, this);
|
||||
this._assignments[param.name] = assignment;
|
||||
}
|
||||
@ -5748,40 +5679,81 @@ Requisition.prototype.getAssignments = function(includeCommand) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Alter the given assignment using the given arg. This function is better than
|
||||
* calling assignment.setConversion(assignment.param.type.parse(arg)) because
|
||||
* it adjusts the args in this requisition to keep things up to date
|
||||
* Alter the given assignment using the given arg.
|
||||
* @param assignment The assignment to alter
|
||||
* @param arg The new value for the assignment. An instance of Argument, or an
|
||||
* instance of Conversion, or null to set the blank value.
|
||||
*/
|
||||
Requisition.prototype.setAssignment = function(assignment, arg) {
|
||||
var originalArgs = assignment.arg.getArgs();
|
||||
var conversion = assignment.param.type.parse(arg);
|
||||
assignment.setConversion(conversion);
|
||||
this._setAssignment(assignment, arg, false);
|
||||
};
|
||||
|
||||
var replacementArgs = arg.getArgs();
|
||||
var maxLen = Math.max(originalArgs.length, replacementArgs.length);
|
||||
for (var i = 0; i < maxLen; i++) {
|
||||
// If there are no more original args, or if the original arg was blank
|
||||
// (i.e. not typed by the user), we'll just need to add at the end
|
||||
if (i >= originalArgs.length || originalArgs[i].type === 'BlankArgument') {
|
||||
this._args.push(replacementArgs[i]);
|
||||
continue;
|
||||
}
|
||||
/**
|
||||
* Internal function to alter the given assignment using the given arg.
|
||||
* @param assignment The assignment to alter
|
||||
* @param arg The new value for the assignment. An instance of Argument, or an
|
||||
* instance of Conversion, or null to set the blank value.
|
||||
* @param skipArgUpdate (default=false) Adjusts the args in this requisition to
|
||||
* keep things up to date. Args should only be skipped when setAssignment is
|
||||
* being called as part of the update process.
|
||||
*/
|
||||
Requisition.prototype._setAssignment = function(assignment, arg, skipArgUpdate) {
|
||||
if (!skipArgUpdate) {
|
||||
var originalArgs = assignment.arg.getArgs();
|
||||
|
||||
var index = this._args.indexOf(originalArgs[i]);
|
||||
if (index === -1) {
|
||||
console.error('Couldn\'t find ', originalArgs[i], ' in ', this._args);
|
||||
throw new Error('Couldn\'t find ' + originalArgs[i]);
|
||||
}
|
||||
// Update the args array
|
||||
var replacementArgs = arg.getArgs();
|
||||
var maxLen = Math.max(originalArgs.length, replacementArgs.length);
|
||||
for (var i = 0; i < maxLen; i++) {
|
||||
// If there are no more original args, or if the original arg was blank
|
||||
// (i.e. not typed by the user), we'll just need to add at the end
|
||||
if (i >= originalArgs.length || originalArgs[i].type === 'BlankArgument') {
|
||||
this._args.push(replacementArgs[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there are no more replacement args, we just remove the original args
|
||||
// Otherwise swap original args and replacements
|
||||
if (i >= replacementArgs.length) {
|
||||
this._args.splice(index, 1);
|
||||
}
|
||||
else {
|
||||
this._args[index] = replacementArgs[i];
|
||||
var index = this._args.indexOf(originalArgs[i]);
|
||||
if (index === -1) {
|
||||
console.error('Couldn\'t find ', originalArgs[i], ' in ', this._args);
|
||||
throw new Error('Couldn\'t find ' + originalArgs[i]);
|
||||
}
|
||||
|
||||
// If there are no more replacement args, we just remove the original args
|
||||
// Otherwise swap original args and replacements
|
||||
if (i >= replacementArgs.length) {
|
||||
this._args.splice(index, 1);
|
||||
}
|
||||
else {
|
||||
this._args[index] = replacementArgs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var conversion;
|
||||
if (arg == null) {
|
||||
conversion = assignment.param.type.getBlank();
|
||||
}
|
||||
else if (typeof arg.getStatus === 'function') {
|
||||
conversion = arg;
|
||||
}
|
||||
else {
|
||||
conversion = assignment.param.type.parse(arg);
|
||||
}
|
||||
|
||||
var oldConversion = assignment.conversion;
|
||||
|
||||
assignment.conversion = conversion;
|
||||
assignment.conversion.assign(assignment);
|
||||
|
||||
if (assignment.conversion.equals(oldConversion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
assignment.onAssignmentChange({
|
||||
assignment: assignment,
|
||||
conversion: assignment.conversion,
|
||||
oldConversion: oldConversion
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -5789,7 +5761,7 @@ Requisition.prototype.setAssignment = function(assignment, arg) {
|
||||
*/
|
||||
Requisition.prototype.setBlankArguments = function() {
|
||||
this.getAssignments().forEach(function(assignment) {
|
||||
assignment.setBlank();
|
||||
this._setAssignment(assignment, null, true);
|
||||
}, this);
|
||||
};
|
||||
|
||||
@ -6148,8 +6120,8 @@ Requisition.prototype.getAssignmentAt = function(cursor) {
|
||||
* @param input (optional) The command to execute. See above.
|
||||
*/
|
||||
Requisition.prototype.exec = function(input) {
|
||||
var command;
|
||||
var args;
|
||||
var command = null;
|
||||
var args = null;
|
||||
var hidden = false;
|
||||
if (input && input.hidden) {
|
||||
hidden = true;
|
||||
@ -6200,33 +6172,58 @@ Requisition.prototype.exec = function(input) {
|
||||
|
||||
this.commandOutputManager.onOutput({ output: output });
|
||||
|
||||
var onDone = function(data) {
|
||||
output.complete(data);
|
||||
};
|
||||
|
||||
var onError = function(error) {
|
||||
console.error(error);
|
||||
output.error = true;
|
||||
output.complete(error);
|
||||
};
|
||||
|
||||
try {
|
||||
var context = exports.createExecutionContext(this);
|
||||
var reply = command.exec(args, context);
|
||||
|
||||
if (reply != null && typeof reply.then === 'function') {
|
||||
reply.then(
|
||||
function(data) { output.complete(data); },
|
||||
function(error) { output.error = true; output.complete(error); });
|
||||
|
||||
output.promise = reply;
|
||||
// Add progress to our promise and add a handler for it here
|
||||
// See bug 659300
|
||||
}
|
||||
else {
|
||||
output.complete(reply);
|
||||
}
|
||||
this._then(reply, onDone, onError);
|
||||
}
|
||||
catch (ex) {
|
||||
console.error(ex);
|
||||
output.error = true;
|
||||
output.complete(ex);
|
||||
onError(ex);
|
||||
}
|
||||
|
||||
this.update('');
|
||||
return output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Different types of promise have different ways of doing 'then'. This is a
|
||||
* catch-all so we can ignore the differences. It also handles concrete values
|
||||
* and calls onDone directly if thing is not a promise.
|
||||
* @param thing The value to test for 'promiseness'
|
||||
* @param onDone The action to take if thing is resolved
|
||||
* @param onError The action to take if thing is rejected
|
||||
*/
|
||||
Requisition.prototype._then = function(thing, onDone, onError) {
|
||||
var then = null;
|
||||
if (thing != null && typeof thing.then === 'function') {
|
||||
// Old GCLI style / simple promises with a then function
|
||||
then = thing.then;
|
||||
}
|
||||
else if (thing != null && thing.promise != null &&
|
||||
typeof thing.promise.then === 'function') {
|
||||
// Q / Mozilla add-ons style
|
||||
then = thing.promise.then;
|
||||
}
|
||||
|
||||
if (then != null) {
|
||||
then(onDone, onError);
|
||||
}
|
||||
else {
|
||||
onDone(thing);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called by the UI when ever the user interacts with a command line input
|
||||
* @param typed The contents of the input field
|
||||
@ -6517,7 +6514,7 @@ Requisition.prototype._split = function(args) {
|
||||
// Special case: if the user enters { console.log('foo'); } then we need to
|
||||
// use the hidden 'eval' command
|
||||
conversion = new Conversion(evalCommand, new ScriptArgument());
|
||||
this.commandAssignment.setConversion(conversion);
|
||||
this._setAssignment(this.commandAssignment, conversion, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6525,8 +6522,8 @@ Requisition.prototype._split = function(args) {
|
||||
|
||||
while (argsUsed <= args.length) {
|
||||
var arg = (argsUsed === 1) ?
|
||||
args[0] :
|
||||
new MergedArgument(args, 0, argsUsed);
|
||||
args[0] :
|
||||
new MergedArgument(args, 0, argsUsed);
|
||||
conversion = this.commandAssignment.param.type.parse(arg);
|
||||
|
||||
// We only want to carry on if this command is a parent command,
|
||||
@ -6544,7 +6541,7 @@ Requisition.prototype._split = function(args) {
|
||||
argsUsed++;
|
||||
}
|
||||
|
||||
this.commandAssignment.setConversion(conversion);
|
||||
this._setAssignment(this.commandAssignment, conversion, true);
|
||||
|
||||
for (var i = 0; i < argsUsed; i++) {
|
||||
args.shift();
|
||||
@ -6590,11 +6587,8 @@ Requisition.prototype._assign = function(args) {
|
||||
if (this.assignmentCount === 1) {
|
||||
var assignment = this.getAssignment(0);
|
||||
if (assignment.param.type instanceof StringType) {
|
||||
var arg = (args.length === 1) ?
|
||||
args[0] :
|
||||
new MergedArgument(args);
|
||||
var conversion = assignment.param.type.parse(arg);
|
||||
assignment.setConversion(conversion);
|
||||
var arg = (args.length === 1) ? args[0] : new MergedArgument(args);
|
||||
this._setAssignment(assignment, arg, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -6639,8 +6633,7 @@ Requisition.prototype._assign = function(args) {
|
||||
arrayArg.addArgument(arg);
|
||||
}
|
||||
else {
|
||||
var conversion = assignment.param.type.parse(arg);
|
||||
assignment.setConversion(conversion);
|
||||
this._setAssignment(assignment, arg, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -6657,7 +6650,7 @@ Requisition.prototype._assign = function(args) {
|
||||
// If not set positionally, and we can't set it non-positionally,
|
||||
// we have to default it to prevent previous values surviving
|
||||
if (!assignment.param.isPositionalAllowed) {
|
||||
assignment.setBlank();
|
||||
this._setAssignment(assignment, null, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6674,7 +6667,7 @@ Requisition.prototype._assign = function(args) {
|
||||
}
|
||||
else {
|
||||
if (args.length === 0) {
|
||||
assignment.setBlank();
|
||||
this._setAssignment(assignment, null, true);
|
||||
}
|
||||
else {
|
||||
var arg = args.splice(0, 1)[0];
|
||||
@ -6688,8 +6681,7 @@ Requisition.prototype._assign = function(args) {
|
||||
this._unassigned.push(new UnassignedAssignment(this, arg));
|
||||
}
|
||||
else {
|
||||
var conversion = assignment.param.type.parse(arg);
|
||||
assignment.setConversion(conversion);
|
||||
this._setAssignment(assignment, arg, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6698,8 +6690,7 @@ Requisition.prototype._assign = function(args) {
|
||||
// Now we need to assign the array argument (if any)
|
||||
Object.keys(arrayArgs).forEach(function(name) {
|
||||
var assignment = this.getAssignment(name);
|
||||
var conversion = assignment.param.type.parse(arrayArgs[name]);
|
||||
assignment.setConversion(conversion);
|
||||
this._setAssignment(assignment, arrayArgs[name], true);
|
||||
}, this);
|
||||
|
||||
// What's left is can't be assigned, but we need to extract
|
||||
@ -6729,17 +6720,31 @@ function Output(options) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when there is data to display
|
||||
* @param data
|
||||
* Called when there is data to display, but the command is still executing
|
||||
* @param data The new data. If the data structure has been altered but the
|
||||
* root object is still the same, The same root object should be passed in the
|
||||
* data parameter.
|
||||
* @param ev Optional additional event data, for example to explain how the
|
||||
* data structure has changed
|
||||
*/
|
||||
Output.prototype.complete = function(data) {
|
||||
Output.prototype.changed = function(data, ev) {
|
||||
this.data = data;
|
||||
|
||||
ev = ev || {};
|
||||
ev.output = this;
|
||||
this.onChange(ev);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when there is data to display, and the command has finished executing
|
||||
* See changed() for details on parameters.
|
||||
*/
|
||||
Output.prototype.complete = function(data, ev) {
|
||||
this.end = new Date();
|
||||
this.duration = this.end.getTime() - this.start.getTime();
|
||||
this.completed = true;
|
||||
|
||||
this.onChange({ output: this });
|
||||
this.changed(data, ev);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -6830,8 +6835,15 @@ exports.createExecutionContext = function(requisition) {
|
||||
document: requisition.document,
|
||||
environment: requisition.environment,
|
||||
createView: view.createView,
|
||||
defer: function() {
|
||||
return Q.defer();
|
||||
},
|
||||
/**
|
||||
* @deprecated Use defer() instead, which does the same thing, but is not
|
||||
* confusingly named
|
||||
*/
|
||||
createPromise: function() {
|
||||
return new Promise();
|
||||
return Q.defer();
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -6856,8 +6868,13 @@ exports.createExecutionContext = function(requisition) {
|
||||
|
||||
define('gcli/promise', ['require', 'exports', 'module' ], function(require, exports, module) {
|
||||
|
||||
Components.utils.import("resource:///modules/devtools/Promise.jsm");
|
||||
exports.Promise = Promise;
|
||||
var imported = {};
|
||||
Components.utils.import("resource://gre/modules/commonjs/promise/core.js",
|
||||
imported);
|
||||
|
||||
exports.defer = imported.Promise.defer;
|
||||
exports.resolve = imported.Promise.resolve;
|
||||
exports.reject = imported.Promise.reject;
|
||||
|
||||
});
|
||||
define("text!gcli/ui/intro.html", [], "\n" +
|
||||
@ -7237,7 +7254,7 @@ FocusManager.prototype._checkShow = function() {
|
||||
|
||||
if (fire) {
|
||||
if (this._debug) {
|
||||
console.debug('FocusManager.onVisibilityChange', ev);
|
||||
console.log('FocusManager.onVisibilityChange', ev);
|
||||
}
|
||||
this.onVisibilityChange(ev);
|
||||
}
|
||||
@ -7735,6 +7752,9 @@ Field.prototype.destroy = function() {
|
||||
delete this.messageElement;
|
||||
};
|
||||
|
||||
// Note: We could/should probably change Fields from working with Conversions
|
||||
// to working with Arguments (Tokens), which makes for less calls to parse()
|
||||
|
||||
/**
|
||||
* Update this field display with the value from this conversion.
|
||||
* Subclasses should provide an implementation of this function.
|
||||
@ -9393,7 +9413,9 @@ Inputter.prototype.textChanged = function() {
|
||||
input.typed = newStr;
|
||||
this._processCaretChange(input);
|
||||
|
||||
this.element.value = newStr;
|
||||
if (this.element.value !== newStr) {
|
||||
this.element.value = newStr;
|
||||
}
|
||||
this.onInputChange({ inputState: input });
|
||||
};
|
||||
|
||||
@ -9469,8 +9491,12 @@ Inputter.prototype._processCaretChange = function(input) {
|
||||
cursor: { start: start, end: end }
|
||||
};
|
||||
|
||||
this.element.selectionStart = start;
|
||||
this.element.selectionEnd = end;
|
||||
if (this.element.selectionStart !== start) {
|
||||
this.element.selectionStart = start;
|
||||
}
|
||||
if (this.element.selectionEnd !== end) {
|
||||
this.element.selectionEnd = end;
|
||||
}
|
||||
|
||||
this._checkAssignment(start);
|
||||
|
||||
@ -9605,7 +9631,7 @@ Inputter.prototype.onKeyUp = function(ev) {
|
||||
// If the user is on a valid value, then we increment the value, but if
|
||||
// they've typed something that's not right we page through predictions
|
||||
if (this.assignment.getStatus() === Status.VALID) {
|
||||
this.requisition.increment(assignment);
|
||||
this.requisition.increment(this.assignment);
|
||||
// See notes on focusManager.onInputChange in onKeyDown
|
||||
if (this.focusManager) {
|
||||
this.focusManager.onInputChange();
|
||||
@ -9629,7 +9655,7 @@ Inputter.prototype.onKeyUp = function(ev) {
|
||||
else {
|
||||
// See notes above for the UP key
|
||||
if (this.assignment.getStatus() === Status.VALID) {
|
||||
this.requisition.decrement(assignment);
|
||||
this.requisition.decrement(this.assignment);
|
||||
// See notes on focusManager.onInputChange in onKeyDown
|
||||
if (this.focusManager) {
|
||||
this.focusManager.onInputChange();
|
||||
@ -10314,7 +10340,7 @@ Tooltip.prototype.selectChoice = function(ev) {
|
||||
* Called by the onFieldChange event on the current Field
|
||||
*/
|
||||
Tooltip.prototype.fieldChanged = function(ev) {
|
||||
this.assignment.setConversion(ev.conversion);
|
||||
this.requisition.setAssignment(this.assignment, ev.conversion.arg);
|
||||
|
||||
var isError = ev.conversion.message != null && ev.conversion.message !== '';
|
||||
this.focusManager.setError(isError);
|
||||
|
@ -163,8 +163,8 @@ function testPrefStatus() {
|
||||
helpers.setInput('pref list');
|
||||
helpers.check({
|
||||
input: 'pref list',
|
||||
hints: '',
|
||||
markup: 'EEEEVEEEE',
|
||||
hints: ' -> pref set',
|
||||
markup: 'IIIIVIIII',
|
||||
status: 'ERROR'
|
||||
});
|
||||
}
|
||||
|
@ -108,8 +108,8 @@ define('gclitest/index', ['require', 'exports', 'module' , 'gclitest/suite', 'gc
|
||||
* @param options Lookup of options that customize test running. Includes:
|
||||
* - window (default=undefined) A reference to the DOM window. If left
|
||||
* undefined then a reduced set of tests will run.
|
||||
* - isNode (default=false) Are we running under NodeJS, specifically, are we
|
||||
* using JSDom, which isn't a 100% complete DOM implementation.
|
||||
* - isJsdom (default=false) Are we running under JSDom, specifically, which
|
||||
* isn't a 100% complete DOM implementation.
|
||||
* Some tests are skipped when using NodeJS.
|
||||
* - display (default=undefined) A reference to a Display implementation.
|
||||
* A reduced set of tests will run if left undefined
|
||||
@ -119,12 +119,12 @@ define('gclitest/index', ['require', 'exports', 'module' , 'gclitest/suite', 'gc
|
||||
* |requisition.exec()| which prevents the display from becoming messed up,
|
||||
* however use of hideExec restricts the set of tests that are run
|
||||
*/
|
||||
exports.run = function(options) {
|
||||
exports.runAsync = function(options, callback) {
|
||||
options = options || {};
|
||||
examiner.mergeDefaultOptions(options);
|
||||
|
||||
examiner.reset();
|
||||
examiner.run(options);
|
||||
examiner.runAsync(options, callback);
|
||||
|
||||
// A better set of default than those specified above, come from the set
|
||||
// that are passed to run().
|
||||
@ -155,13 +155,6 @@ define('gclitest/index', ['require', 'exports', 'module' , 'gclitest/suite', 'gc
|
||||
|
||||
// setTimeout keeps stack traces clear of RequireJS frames
|
||||
window.setTimeout(function() {
|
||||
var options = {
|
||||
window: window,
|
||||
display: window.display,
|
||||
hideExec: true
|
||||
};
|
||||
exports.run(options);
|
||||
|
||||
window.createDebugCheck = function() {
|
||||
require([ 'gclitest/helpers' ], function(helpers) {
|
||||
helpers.setup(options);
|
||||
@ -198,7 +191,15 @@ define('gclitest/index', ['require', 'exports', 'module' , 'gclitest/suite', 'gc
|
||||
mockCommands.setup();
|
||||
});
|
||||
};
|
||||
window.testCommands();
|
||||
|
||||
var options = {
|
||||
window: window,
|
||||
display: window.display,
|
||||
hideExec: true
|
||||
};
|
||||
exports.runAsync(options, function() {
|
||||
window.testCommands();
|
||||
});
|
||||
}, 10);
|
||||
|
||||
return {
|
||||
@ -326,25 +327,6 @@ examiner.mergeDefaultOptions = function(options) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Run the tests defined in the test suite synchronously
|
||||
*/
|
||||
examiner.run = function(options) {
|
||||
Object.keys(examiner.suites).forEach(function(suiteName) {
|
||||
var suite = examiner.suites[suiteName];
|
||||
suite.run(options);
|
||||
}.bind(this));
|
||||
|
||||
if (options.detailedResultLog) {
|
||||
examiner.detailedResultLog();
|
||||
}
|
||||
else {
|
||||
console.log('Completed test suite');
|
||||
}
|
||||
|
||||
return examiner.suites;
|
||||
};
|
||||
|
||||
/**
|
||||
* Run all the tests asynchronously
|
||||
*/
|
||||
@ -477,21 +459,6 @@ Suite.prototype.reset = function() {
|
||||
}, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Run all the tests in this suite synchronously
|
||||
*/
|
||||
Suite.prototype.run = function(options) {
|
||||
if (!this._setup(options)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.keys(this.tests).forEach(function(testName) {
|
||||
this.tests[testName].run(options);
|
||||
}, this);
|
||||
|
||||
this._shutdown(options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Run all the tests in this suite asynchronously
|
||||
*/
|
||||
@ -636,6 +603,9 @@ function Test(suite, name, func) {
|
||||
this.func = func;
|
||||
this.title = name.replace(/^test/, '').replace(/([A-Z])/g, ' $1');
|
||||
|
||||
this.outstanding = [];
|
||||
this.callback = undefined;
|
||||
|
||||
this.failures = [];
|
||||
this.status = stati.notrun;
|
||||
this.checks = 0;
|
||||
@ -645,16 +615,20 @@ function Test(suite, name, func) {
|
||||
* Reset the test to its original state
|
||||
*/
|
||||
Test.prototype.reset = function() {
|
||||
this.outstanding = [];
|
||||
this.callback = undefined;
|
||||
|
||||
this.failures = [];
|
||||
this.status = stati.notrun;
|
||||
this.checks = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Run just a single test
|
||||
* Run all the tests in this suite asynchronously
|
||||
*/
|
||||
Test.prototype.run = function(options) {
|
||||
Test.prototype.runAsync = function(options, callback) {
|
||||
assert.currentTest = this;
|
||||
this.callback = callback;
|
||||
this.status = stati.executing;
|
||||
this.failures = [];
|
||||
this.checks = 0;
|
||||
@ -675,18 +649,20 @@ Test.prototype.run = function(options) {
|
||||
}
|
||||
|
||||
assert.currentTest = null;
|
||||
|
||||
this.checkFinish();
|
||||
};
|
||||
|
||||
/**
|
||||
* Run all the tests in this suite asynchronously
|
||||
* Check to see if the currently executing test is completed (i.e. the list of
|
||||
* outstanding tasks has all been completed)
|
||||
*/
|
||||
Test.prototype.runAsync = function(options, callback) {
|
||||
setTimeout(function() {
|
||||
this.run(options);
|
||||
if (typeof callback === 'function') {
|
||||
callback();
|
||||
Test.prototype.checkFinish = function() {
|
||||
if (this.outstanding.length == 0) {
|
||||
if (typeof this.callback === 'function') {
|
||||
this.callback();
|
||||
}
|
||||
}.bind(this), delay);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -892,21 +868,25 @@ define('gclitest/testCanon', ['require', 'exports', 'module' , 'gclitest/helpers
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
define('gclitest/helpers', ['require', 'exports', 'module' , 'test/assert', 'gcli/util'], function(require, exports, module) {
|
||||
define('gclitest/helpers', ['require', 'exports', 'module' , 'test/assert'], function(require, exports, module) {
|
||||
|
||||
|
||||
var test = require('test/assert');
|
||||
var util = require('gcli/util');
|
||||
|
||||
// A copy of this code exists in firefox mochitests; when updated here it
|
||||
// should be updated there too. Hence the use of an exports synonym for non
|
||||
// AMD contexts.
|
||||
var helpers = exports;
|
||||
|
||||
helpers._display = undefined;
|
||||
helpers._options = undefined;
|
||||
|
||||
helpers.setup = function(options) {
|
||||
helpers._options = options;
|
||||
helpers._display = options.display;
|
||||
};
|
||||
|
||||
helpers.shutdown = function(options) {
|
||||
helpers._options = undefined;
|
||||
helpers._display = undefined;
|
||||
};
|
||||
|
||||
@ -1025,6 +1005,16 @@ helpers.setInput = function(typed, cursor) {
|
||||
if (cursor) {
|
||||
helpers._display.inputter.setCursor({ start: cursor, end: cursor });
|
||||
}
|
||||
else {
|
||||
// This is a hack because jsdom appears to not handle cursor updates
|
||||
// in the same way as most browsers.
|
||||
if (helpers._options.isJsdom) {
|
||||
helpers._display.inputter.setCursor({
|
||||
start: typed.length,
|
||||
end: typed.length
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
helpers._display.focusManager.onInputChange();
|
||||
};
|
||||
@ -1589,7 +1579,7 @@ exports.testElement = function(options) {
|
||||
test.ok(assign1.arg.type === 'BlankArgument');
|
||||
test.is(undefined, assign1.value);
|
||||
|
||||
if (!options.isNode) {
|
||||
if (!options.isJsdom) {
|
||||
update({ typed: 'tse :root', cursor: { start: 9, end: 9 } });
|
||||
test.is( 'VVVVVVVVV', statuses);
|
||||
test.is(Status.VALID, status);
|
||||
@ -1625,7 +1615,7 @@ exports.testElement = function(options) {
|
||||
test.is(undefined, assign1.value);
|
||||
}
|
||||
else {
|
||||
test.log('Skipping :root test due to jsdom (from isNode)');
|
||||
test.log('Skipping :root test due to jsdom');
|
||||
}
|
||||
|
||||
update({ typed: 'tse #', cursor: { start: 5, end: 5 } });
|
||||
@ -2360,7 +2350,7 @@ exports.testActivate = function(options) {
|
||||
|
||||
helpers.setInput('tsg d');
|
||||
helpers.check({
|
||||
hints: ' [options]'
|
||||
hints: ' [options] -> ccc'
|
||||
});
|
||||
|
||||
helpers.setInput('tsg aa');
|
||||
@ -2774,9 +2764,10 @@ var mockDoc = {
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
define('gclitest/testFocus', ['require', 'exports', 'module' , 'gclitest/helpers', 'gclitest/mockCommands'], function(require, exports, module) {
|
||||
define('gclitest/testFocus', ['require', 'exports', 'module' , 'test/assert', 'gclitest/helpers', 'gclitest/mockCommands'], function(require, exports, module) {
|
||||
|
||||
|
||||
var test = require('test/assert');
|
||||
var helpers = require('gclitest/helpers');
|
||||
var mockCommands = require('gclitest/mockCommands');
|
||||
|
||||
@ -2791,6 +2782,11 @@ exports.shutdown = function(options) {
|
||||
};
|
||||
|
||||
exports.testBasic = function(options) {
|
||||
if (options.isJsdom) {
|
||||
test.log('jsdom does not pass on focus events properly, skipping testBasic');
|
||||
return;
|
||||
}
|
||||
|
||||
helpers.focusInput();
|
||||
helpers.exec(options, 'help');
|
||||
|
||||
@ -3343,9 +3339,8 @@ exports.testHidden = function(options) {
|
||||
helpers.setInput('tshidde');
|
||||
helpers.check({
|
||||
input: 'tshidde',
|
||||
markup: 'EEEEEEE',
|
||||
status: 'ERROR',
|
||||
hints: '',
|
||||
hints: ' -> tse',
|
||||
status: 'ERROR'
|
||||
});
|
||||
|
||||
helpers.setInput('tshidden');
|
||||
@ -3470,10 +3465,11 @@ exports.testHidden = function(options) {
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
define('gclitest/testIntro', ['require', 'exports', 'module' , 'gclitest/helpers', 'test/assert'], function(require, exports, module) {
|
||||
define('gclitest/testIntro', ['require', 'exports', 'module' , 'gclitest/helpers', 'test/assert', 'gcli/canon'], function(require, exports, module) {
|
||||
|
||||
var helpers = require('gclitest/helpers');
|
||||
var test = require('test/assert');
|
||||
var canon = require('gcli/canon');
|
||||
|
||||
exports.setup = function(options) {
|
||||
helpers.setup(options);
|
||||
@ -3484,8 +3480,8 @@ define('gclitest/testIntro', ['require', 'exports', 'module' , 'gclitest/helpers
|
||||
};
|
||||
|
||||
exports.testIntroStatus = function(options) {
|
||||
if (options.isFirefox) {
|
||||
test.log('Skipping testIntroStatus in Firefox.');
|
||||
if (canon.getCommand('intro') == null) {
|
||||
test.log('Skipping testIntroStatus; missing intro command.');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3507,8 +3503,8 @@ define('gclitest/testIntro', ['require', 'exports', 'module' , 'gclitest/helpers
|
||||
};
|
||||
|
||||
exports.testIntroExec = function(options) {
|
||||
if (options.isFirefox) {
|
||||
test.log('Skipping testIntroExec in Firefox.');
|
||||
if (canon.getCommand('intro') == null) {
|
||||
test.log('Skipping testIntroStatus; missing intro command.');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3683,7 +3679,10 @@ exports.testBasic = function(options) {
|
||||
input('{ document.title');
|
||||
check('VVVVVVVVVVVVVVVV', Status.VALID, 'document.title', 0);
|
||||
|
||||
test.ok('donteval' in options.window, 'donteval exists');
|
||||
if (!options.isJsdom) {
|
||||
// jsdom causes an eval here, maybe that's node/v8?
|
||||
test.ok('donteval' in options.window, 'donteval exists');
|
||||
}
|
||||
|
||||
input('{ don');
|
||||
check('VVIII', Status.ERROR, 'don', 'donteval');
|
||||
@ -3832,12 +3831,12 @@ exports.testComplete = function(options) {
|
||||
check('{ wind', COMPLETES_TO, '{ window', 0);
|
||||
check('{ window.docum', COMPLETES_TO, '{ window.document', 0);
|
||||
|
||||
// Bug 717228: This fails under node
|
||||
if (!options.isNode) {
|
||||
// Bug 717228: This fails under jsdom
|
||||
if (!options.isJsdom) {
|
||||
check('{ window.document.titl', COMPLETES_TO, '{ window.document.title ', 0);
|
||||
}
|
||||
else {
|
||||
test.log('Running under Node. Skipping tests due to bug 717228.');
|
||||
test.log('Skipping tests due to jsdom and bug 717228.');
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -4008,61 +4007,66 @@ exports.testNode = function(options) {
|
||||
}
|
||||
});
|
||||
|
||||
helpers.setInput('tse :root');
|
||||
helpers.check({
|
||||
input: 'tse :root',
|
||||
hints: ' [options]',
|
||||
markup: 'VVVVVVVVV',
|
||||
cursor: 9,
|
||||
current: 'node',
|
||||
status: 'VALID',
|
||||
args: {
|
||||
command: { name: 'tse' },
|
||||
node: { arg: ' :root', status: 'VALID' },
|
||||
nodes: { status: 'VALID' },
|
||||
nodes2: { status: 'VALID' }
|
||||
}
|
||||
});
|
||||
if (options.isJsdom) {
|
||||
test.log('skipping node tests because jsdom');
|
||||
}
|
||||
else {
|
||||
helpers.setInput('tse :root');
|
||||
helpers.check({
|
||||
input: 'tse :root',
|
||||
hints: ' [options]',
|
||||
markup: 'VVVVVVVVV',
|
||||
cursor: 9,
|
||||
current: 'node',
|
||||
status: 'VALID',
|
||||
args: {
|
||||
command: { name: 'tse' },
|
||||
node: { arg: ' :root', status: 'VALID' },
|
||||
nodes: { status: 'VALID' },
|
||||
nodes2: { status: 'VALID' }
|
||||
}
|
||||
});
|
||||
|
||||
helpers.setInput('tse :root ');
|
||||
helpers.check({
|
||||
input: 'tse :root ',
|
||||
hints: '[options]',
|
||||
markup: 'VVVVVVVVVV',
|
||||
cursor: 10,
|
||||
current: 'node',
|
||||
status: 'VALID',
|
||||
args: {
|
||||
command: { name: 'tse' },
|
||||
node: { arg: ' :root ', status: 'VALID' },
|
||||
nodes: { status: 'VALID' },
|
||||
nodes2: { status: 'VALID' }
|
||||
}
|
||||
});
|
||||
test.is(requisition.getAssignment('node').value.tagName,
|
||||
'HTML',
|
||||
'root id');
|
||||
helpers.setInput('tse :root ');
|
||||
helpers.check({
|
||||
input: 'tse :root ',
|
||||
hints: '[options]',
|
||||
markup: 'VVVVVVVVVV',
|
||||
cursor: 10,
|
||||
current: 'node',
|
||||
status: 'VALID',
|
||||
args: {
|
||||
command: { name: 'tse' },
|
||||
node: { arg: ' :root ', status: 'VALID' },
|
||||
nodes: { status: 'VALID' },
|
||||
nodes2: { status: 'VALID' }
|
||||
}
|
||||
});
|
||||
test.is(requisition.getAssignment('node').value.tagName,
|
||||
'HTML',
|
||||
'root id');
|
||||
|
||||
helpers.setInput('tse #gcli-nomatch');
|
||||
helpers.check({
|
||||
input: 'tse #gcli-nomatch',
|
||||
hints: ' [options]',
|
||||
markup: 'VVVVIIIIIIIIIIIII',
|
||||
cursor: 17,
|
||||
current: 'node',
|
||||
status: 'ERROR',
|
||||
args: {
|
||||
command: { name: 'tse' },
|
||||
node: {
|
||||
value: undefined,
|
||||
arg: ' #gcli-nomatch',
|
||||
status: 'INCOMPLETE',
|
||||
message: 'No matches'
|
||||
},
|
||||
nodes: { status: 'VALID' },
|
||||
nodes2: { status: 'VALID' }
|
||||
}
|
||||
});
|
||||
helpers.setInput('tse #gcli-nomatch');
|
||||
helpers.check({
|
||||
input: 'tse #gcli-nomatch',
|
||||
hints: ' [options]',
|
||||
markup: 'VVVVIIIIIIIIIIIII',
|
||||
cursor: 17,
|
||||
current: 'node',
|
||||
status: 'ERROR',
|
||||
args: {
|
||||
command: { name: 'tse' },
|
||||
node: {
|
||||
value: undefined,
|
||||
arg: ' #gcli-nomatch',
|
||||
status: 'INCOMPLETE',
|
||||
message: 'No matches'
|
||||
},
|
||||
nodes: { status: 'VALID' },
|
||||
nodes2: { status: 'VALID' }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
helpers.setInput('tse #');
|
||||
helpers.check({
|
||||
@ -4131,6 +4135,11 @@ exports.testNode = function(options) {
|
||||
exports.testNodes = function(options) {
|
||||
var requisition = options.display.requisition;
|
||||
|
||||
if (options.isJsdom) {
|
||||
test.log('skipping node tests because jsdom');
|
||||
return;
|
||||
}
|
||||
|
||||
helpers.setInput('tse :root --nodes *');
|
||||
helpers.check({
|
||||
input: 'tse :root --nodes *',
|
||||
@ -4236,13 +4245,14 @@ exports.testNodes = function(options) {
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
define('gclitest/testPref', ['require', 'exports', 'module' , 'gcli/commands/pref', 'gclitest/helpers', 'gclitest/mockSettings', 'test/assert'], function(require, exports, module) {
|
||||
define('gclitest/testPref', ['require', 'exports', 'module' , 'gcli/commands/pref', 'gclitest/helpers', 'gclitest/mockSettings', 'test/assert', 'gcli/canon'], function(require, exports, module) {
|
||||
|
||||
|
||||
var pref = require('gcli/commands/pref');
|
||||
var helpers = require('gclitest/helpers');
|
||||
var mockSettings = require('gclitest/mockSettings');
|
||||
var test = require('test/assert');
|
||||
var canon = require('gcli/canon');
|
||||
|
||||
|
||||
exports.setup = function(options) {
|
||||
@ -4270,6 +4280,11 @@ exports.testPrefShowStatus = function(options) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (canon.getCommand('intro') == null) {
|
||||
test.log('Skipping testIntroStatus; missing intro command.');
|
||||
return;
|
||||
}
|
||||
|
||||
helpers.setInput('pref s');
|
||||
helpers.check({
|
||||
typed: 'pref s',
|
||||
@ -4333,6 +4348,11 @@ exports.testPrefSetStatus = function(options) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (canon.getCommand('intro') == null) {
|
||||
test.log('Skipping testIntroStatus; missing intro command.');
|
||||
return;
|
||||
}
|
||||
|
||||
helpers.setInput('pref s');
|
||||
helpers.check({
|
||||
typed: 'pref s',
|
||||
@ -4352,7 +4372,7 @@ exports.testPrefSetStatus = function(options) {
|
||||
helpers.setInput('pref xxx');
|
||||
helpers.check({
|
||||
typed: 'pref xxx',
|
||||
markup: 'EEEEVEEE',
|
||||
markup: 'IIIIVIII',
|
||||
status: 'ERROR'
|
||||
});
|
||||
|
||||
@ -4395,6 +4415,11 @@ exports.testPrefExec = function(options) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (canon.getCommand('intro') == null) {
|
||||
test.log('Skipping testIntroStatus; missing intro command.');
|
||||
return;
|
||||
}
|
||||
|
||||
var initialAllowSet = pref.allowSet.value;
|
||||
pref.allowSet.value = false;
|
||||
|
||||
@ -4744,12 +4769,11 @@ exports.testPredictions = function(options) {
|
||||
var resource3 = types.getType({ name: 'resource', include: 'text/css' });
|
||||
var options3 = resource3.getLookup();
|
||||
// jsdom fails to support digging into stylesheets
|
||||
if (!options.isNode) {
|
||||
if (!options.isJsdom) {
|
||||
test.ok(options3.length >= 1, 'have resources');
|
||||
}
|
||||
else {
|
||||
test.log('Running under Node. ' +
|
||||
'Skipping checks due to jsdom document.stylsheets support.');
|
||||
test.log('Skipping checks due to jsdom document.stylsheets support.');
|
||||
}
|
||||
options3.forEach(function(prediction) {
|
||||
checkPrediction(resource3, prediction);
|
||||
@ -5018,7 +5042,7 @@ exports.testChange = function(options) {
|
||||
define('gclitest/testSpell', ['require', 'exports', 'module' , 'test/assert', 'gcli/types/spell'], function(require, exports, module) {
|
||||
|
||||
var test = require('test/assert');
|
||||
var Speller = require('gcli/types/spell').Speller;
|
||||
var spell = require('gcli/types/spell');
|
||||
|
||||
exports.setup = function() {
|
||||
};
|
||||
@ -5032,15 +5056,14 @@ exports.testSpellerSimple = function(options) {
|
||||
return;
|
||||
}
|
||||
|
||||
var speller = new Speller();
|
||||
speller.train(Object.keys(options.window));
|
||||
var alternatives = Object.keys(options.window);
|
||||
|
||||
test.is(speller.correct('document'), 'document');
|
||||
test.is(speller.correct('documen'), 'document');
|
||||
test.is(speller.correct('ocument'), 'document');
|
||||
test.is(speller.correct('odcument'), 'document');
|
||||
test.is(spell.correct('document', alternatives), 'document');
|
||||
test.is(spell.correct('documen', alternatives), 'document');
|
||||
test.is(spell.correct('ocument', alternatives), 'document');
|
||||
test.is(spell.correct('odcument', alternatives), 'document');
|
||||
|
||||
test.is(speller.correct('========='), null);
|
||||
test.is(spell.correct('=========', alternatives), undefined);
|
||||
};
|
||||
|
||||
|
||||
@ -5458,7 +5481,7 @@ function type(typed, tests, options) {
|
||||
inputter.setCursor({ start: tests.cursor, end: tests.cursor });
|
||||
}
|
||||
|
||||
if (!options.isNode) {
|
||||
if (!options.isJsdom) {
|
||||
if (tests.important) {
|
||||
test.ok(tooltip.field.isImportant, 'Important for ' + typed);
|
||||
}
|
||||
@ -5488,8 +5511,8 @@ exports.testActivate = function(options) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.isNode) {
|
||||
test.log('Running under Node. Reduced checks due to JSDom.textContent');
|
||||
if (options.isJsdom) {
|
||||
test.log('Reduced checks due to JSDom.textContent');
|
||||
}
|
||||
|
||||
type(' ', { }, options);
|
||||
@ -5506,11 +5529,9 @@ exports.testActivate = function(options) {
|
||||
|
||||
type('tsb tt', {
|
||||
important: true,
|
||||
options: [ ],
|
||||
error: 'Can\'t use \'tt\'.'
|
||||
options: [ 'true' ]
|
||||
}, options);
|
||||
|
||||
|
||||
type('asdf', {
|
||||
important: false,
|
||||
options: [ ],
|
||||
@ -5572,9 +5593,8 @@ function forEachType(options, callback) {
|
||||
}
|
||||
|
||||
exports.testDefault = function(options) {
|
||||
if (options.isNode) {
|
||||
test.log('Running under Node. ' +
|
||||
'Skipping tests due to issues with resource type.');
|
||||
if (options.isJsdom) {
|
||||
test.log('Skipping tests due to issues with resource type.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,11 @@ var a = function() {
|
||||
var anon = a();
|
||||
anon.displayName = "anonFunc";
|
||||
|
||||
var inferred = a();
|
||||
|
||||
function evalCall() {
|
||||
eval("anon();");
|
||||
eval("inferred();");
|
||||
}
|
||||
|
||||
</script>
|
||||
|
@ -3,6 +3,9 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests that anonymous functions appear in the stack frame list with either
|
||||
// their displayName property or a SpiderMonkey-inferred name.
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
@ -36,13 +39,35 @@ function testAnonCall() {
|
||||
is(frames.querySelector("#stackframe-0 .dbg-stackframe-name").getAttribute("value"),
|
||||
"anonFunc", "Frame name should be anonFunc");
|
||||
|
||||
resumeAndFinish();
|
||||
testInferredName();
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.evalCall();
|
||||
}
|
||||
|
||||
function testInferredName() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let frames = gDebugger.DebuggerView.StackFrames._frames;
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
|
||||
"Should have three frames.");
|
||||
|
||||
is(frames.querySelector("#stackframe-0 .dbg-stackframe-name").getAttribute("value"),
|
||||
"a/<", "Frame name should be a/<");
|
||||
|
||||
resumeAndFinish();
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebugger.DebuggerController.activeThread.resume();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
|
@ -6,9 +6,9 @@ const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/devtools/dbg-server.jsm", tempScope);
|
||||
Cu.import("resource:///modules/devtools/dbg-client.jsm", tempScope);
|
||||
Cu.import("resource:///modules/Services.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/devtools/dbg-client.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/Services.jsm", tempScope);
|
||||
let DebuggerServer = tempScope.DebuggerServer;
|
||||
let DebuggerTransport = tempScope.DebuggerTransport;
|
||||
let DebuggerClient = tempScope.DebuggerClient;
|
||||
|
@ -35,6 +35,7 @@ const PREF_RECENT_FILES_MAX = "devtools.scratchpad.recentFilesMax";
|
||||
const BUTTON_POSITION_SAVE = 0;
|
||||
const BUTTON_POSITION_CANCEL = 1;
|
||||
const BUTTON_POSITION_DONT_SAVE = 2;
|
||||
const BUTTON_POSITION_REVERT=0;
|
||||
|
||||
let keysbundle = Services.strings.createBundle("chrome://global-platform/locale/platformKeys.properties");
|
||||
|
||||
@ -922,6 +923,72 @@ var Scratchpad = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Restore content from saved version of current file.
|
||||
*
|
||||
* @param function aCallback
|
||||
* Optional function you want to call when file is saved
|
||||
*/
|
||||
revertFile: function SP_revertFile(aCallback)
|
||||
{
|
||||
|
||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
file.initWithPath(this.filename);
|
||||
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.importFromFile(file, false, function(aStatus, aContent) {
|
||||
if (aCallback) {
|
||||
aCallback(aStatus);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Prompt to revert scratchpad if it has unsaved changes.
|
||||
*
|
||||
* @param function aCallback
|
||||
* Optional function you want to call when file is saved. The callback
|
||||
* receives three arguments:
|
||||
* - aRevert (boolean) - tells if the file has been reverted.
|
||||
* - status (number) - the file revert status result (if the file was
|
||||
* saved).
|
||||
*/
|
||||
promptRevert: function SP_promptRervert(aCallback)
|
||||
{
|
||||
if (this.filename) {
|
||||
let ps = Services.prompt;
|
||||
let flags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_REVERT +
|
||||
ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL;
|
||||
|
||||
let button = ps.confirmEx(window,
|
||||
this.strings.GetStringFromName("confirmRevert.title"),
|
||||
this.strings.GetStringFromName("confirmRevert"),
|
||||
flags, null, null, null, null, {});
|
||||
if (button == BUTTON_POSITION_CANCEL) {
|
||||
if (aCallback) {
|
||||
aCallback(false);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
if (button == BUTTON_POSITION_REVERT) {
|
||||
this.revertFile(function(aStatus) {
|
||||
if(aCallback){
|
||||
aCallback(true, aStatus);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (aCallback) {
|
||||
aCallback(false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Open the Error Console.
|
||||
*/
|
||||
@ -1107,6 +1174,14 @@ var Scratchpad = {
|
||||
_onDirtyChanged: function SP__onDirtyChanged(aEvent)
|
||||
{
|
||||
Scratchpad._updateTitle();
|
||||
if (Scratchpad.filename) {
|
||||
if (Scratchpad.editor.dirty) {
|
||||
document.getElementById("sp-cmd-revert").removeAttribute("disabled");
|
||||
}
|
||||
else {
|
||||
document.getElementById("sp-cmd-revert").setAttribute("disabled", true);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -33,6 +33,7 @@
|
||||
<command id="sp-cmd-clearRecentFiles" oncommand="Scratchpad.clearRecentFiles();"/>
|
||||
<command id="sp-cmd-save" oncommand="Scratchpad.saveFile();"/>
|
||||
<command id="sp-cmd-saveas" oncommand="Scratchpad.saveFileAs();"/>
|
||||
<command id="sp-cmd-revert" oncommand="Scratchpad.promptRevert();" disabled="true"/>
|
||||
|
||||
<!-- TODO: bug 650340 - implement printFile()
|
||||
<command id="sp-cmd-printFile" oncommand="Scratchpad.printFile();" disabled="true"/>
|
||||
@ -132,6 +133,10 @@
|
||||
label="&saveFileAsCmd.label;"
|
||||
accesskey="&saveFileAsCmd.accesskey;"
|
||||
command="sp-cmd-saveas"/>
|
||||
<menuitem id="sp-menu-revert"
|
||||
label="&revertCmd.label;"
|
||||
accesskey="&revertCmd.accesskey;"
|
||||
command="sp-cmd-revert"/>
|
||||
<menuseparator/>
|
||||
|
||||
<!-- TODO: bug 650340 - implement printFile
|
||||
|
@ -33,6 +33,7 @@ MOCHITEST_BROWSER_FILES = \
|
||||
browser_scratchpad_bug_650760_help_key.js \
|
||||
browser_scratchpad_bug_651942_recent_files.js \
|
||||
browser_scratchpad_bug756681_display_non_error_exceptions.js \
|
||||
browser_scratchpad_bug_751744_revert_to_saved.js \
|
||||
head.js \
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -0,0 +1,137 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let tempScope = {};
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
|
||||
let NetUtil = tempScope.NetUtil;
|
||||
let FileUtils = tempScope.FileUtils;
|
||||
|
||||
// Reference to the Scratchpad object.
|
||||
let gScratchpad;
|
||||
|
||||
// Reference to the temporary nsIFiles.
|
||||
let gFile;
|
||||
|
||||
// Temporary file name.
|
||||
let gFileName = "testFileForBug751744.tmp"
|
||||
|
||||
|
||||
// Content for the temporary file.
|
||||
let gFileContent = "/* this file is already saved */\n" +
|
||||
"function foo() { alert('bar') }";
|
||||
let gLength = gFileContent.length;
|
||||
|
||||
// Reference to the menu entry.
|
||||
let menu;
|
||||
|
||||
function startTest()
|
||||
{
|
||||
gScratchpad = gScratchpadWindow.Scratchpad;
|
||||
menu = gScratchpadWindow.document.getElementById("sp-menu-revert");
|
||||
createAndLoadTemporaryFile();
|
||||
}
|
||||
|
||||
function testAfterSaved() {
|
||||
// Check if the revert menu is disabled as the file is at saved state.
|
||||
ok(menu.hasAttribute("disabled"), "The revert menu entry is disabled.");
|
||||
|
||||
// chancging the text in the file
|
||||
gScratchpad.setText("\nfoo();", gLength, gLength);
|
||||
// Checking the text got changed
|
||||
is(gScratchpad.getText(), gFileContent + "\nfoo();",
|
||||
"The text changed the first time.");
|
||||
|
||||
// Revert menu now should be enabled.
|
||||
ok(!menu.hasAttribute("disabled"),
|
||||
"The revert menu entry is enabled after changing text first time");
|
||||
|
||||
// reverting back to last saved state.
|
||||
gScratchpad.revertFile(testAfterRevert);
|
||||
}
|
||||
|
||||
function testAfterRevert() {
|
||||
// Check if the file's text got reverted
|
||||
is(gScratchpad.getText(), gFileContent,
|
||||
"The text reverted back to original text.");
|
||||
// The revert menu should be disabled again.
|
||||
ok(menu.hasAttribute("disabled"),
|
||||
"The revert menu entry is disabled after reverting.");
|
||||
|
||||
// chancging the text in the file again
|
||||
gScratchpad.setText("\nalert(foo.toSource());", gLength, gLength);
|
||||
// Saving the file.
|
||||
gScratchpad.saveFile(testAfterSecondSave);
|
||||
}
|
||||
|
||||
function testAfterSecondSave() {
|
||||
// revert menu entry should be disabled.
|
||||
ok(menu.hasAttribute("disabled"),
|
||||
"The revert menu entry is disabled after saving.");
|
||||
|
||||
// changing the text.
|
||||
gScratchpad.setText("\nfoo();", gLength + 23, gLength + 23);
|
||||
|
||||
// revert menu entry should get enabled yet again.
|
||||
ok(!menu.hasAttribute("disabled"),
|
||||
"The revert menu entry is enabled after changing text third time");
|
||||
|
||||
// reverting back to last saved state.
|
||||
gScratchpad.revertFile(testAfterSecondRevert);
|
||||
}
|
||||
|
||||
function testAfterSecondRevert() {
|
||||
// Check if the file's text got reverted
|
||||
is(gScratchpad.getText(), gFileContent + "\nalert(foo.toSource());",
|
||||
"The text reverted back to the changed saved text.");
|
||||
// The revert menu should be disabled again.
|
||||
ok(menu.hasAttribute("disabled"),
|
||||
"Revert menu entry is disabled after reverting to changed saved state.");
|
||||
gFile.remove(false);
|
||||
gFile = null;
|
||||
gScratchpad = null;
|
||||
}
|
||||
|
||||
function createAndLoadTemporaryFile()
|
||||
{
|
||||
// Create a temporary file.
|
||||
gFile = FileUtils.getFile("TmpD", [gFileName]);
|
||||
gFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
|
||||
|
||||
// Write the temporary file.
|
||||
let fout = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
fout.init(gFile.QueryInterface(Ci.nsILocalFile), 0x02 | 0x08 | 0x20,
|
||||
0644, fout.DEFER_OPEN);
|
||||
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
let fileContentStream = converter.convertToInputStream(gFileContent);
|
||||
|
||||
NetUtil.asyncCopy(fileContentStream, fout, tempFileSaved);
|
||||
}
|
||||
|
||||
function tempFileSaved(aStatus)
|
||||
{
|
||||
ok(Components.isSuccessCode(aStatus),
|
||||
"the temporary file was saved successfully");
|
||||
|
||||
// Import the file into Scratchpad.
|
||||
gScratchpad.setFilename(gFile.path);
|
||||
gScratchpad.importFromFile(gFile.QueryInterface(Ci.nsILocalFile), true,
|
||||
testAfterSaved);
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(startTest);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>test reverting to last saved state of" +
|
||||
" a file </p>";
|
||||
}
|
@ -15,6 +15,8 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource:///modules/devtools/Commands.jsm");
|
||||
|
||||
const Node = Components.interfaces.nsIDOMNode;
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "console",
|
||||
"resource://gre/modules/devtools/Console.jsm");
|
||||
|
||||
@ -137,6 +139,28 @@ DeveloperToolbar.prototype.focus = function DT_focus()
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called from browser.xul in response to menu-click or keyboard shortcut to
|
||||
* toggle the toolbar
|
||||
*/
|
||||
DeveloperToolbar.prototype.focusToggle = function DT_focusToggle()
|
||||
{
|
||||
if (this.visible) {
|
||||
// If we have focus then the active element is the HTML input contained
|
||||
// inside the xul input element
|
||||
var active = this._chromeWindow.document.activeElement;
|
||||
var position = this._input.compareDocumentPosition(active);
|
||||
if (position & Node.DOCUMENT_POSITION_CONTAINED_BY) {
|
||||
this.hide();
|
||||
}
|
||||
else {
|
||||
this._input.focus();
|
||||
}
|
||||
} else {
|
||||
this.show(true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Even if the user has not clicked on 'Got it' in the intro, we only show it
|
||||
* once per session.
|
||||
|
@ -758,6 +758,87 @@ StyleEditor.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Decode a CSS source string to unicode according to the character set rules
|
||||
* defined in <http://www.w3.org/TR/CSS2/syndata.html#charset>.
|
||||
*
|
||||
* @param string aString
|
||||
* Source of a CSS stylesheet, loaded from file or cache.
|
||||
* @param string aChannelCharset
|
||||
* Charset of the source string if set by the HTTP channel.
|
||||
* @return string
|
||||
* The CSS string, in unicode.
|
||||
*/
|
||||
_decodeCSSCharset: function SE__decodeCSSCharset(aString, aChannelCharset)
|
||||
{
|
||||
// StyleSheet's charset can be specified from multiple sources
|
||||
|
||||
if (aChannelCharset.length > 0) {
|
||||
// step 1 of syndata.html: charset given in HTTP header.
|
||||
return this._convertToUnicode(aString, aChannelCharset);
|
||||
}
|
||||
|
||||
let sheet = this.styleSheet;
|
||||
if (sheet) {
|
||||
// Do we have a @charset rule in the stylesheet?
|
||||
// step 2 of syndata.html (without the BOM check).
|
||||
if (sheet.cssRules) {
|
||||
let rules = sheet.cssRules;
|
||||
if (rules.length
|
||||
&& rules.item(0).type == Ci.nsIDOMCSSRule.CHARSET_RULE) {
|
||||
return this._convertToUnicode(aString, rules.item(0).encoding);
|
||||
}
|
||||
}
|
||||
|
||||
if (sheet.ownerNode) {
|
||||
// step 3: see <link charset="…">
|
||||
let linkCharset = sheet.ownerNode.getAttribute("charset");
|
||||
if (linkCharset != null) {
|
||||
return this._convertToUnicode(aString, linkCharset);
|
||||
}
|
||||
}
|
||||
|
||||
// step 4 (1 of 2): charset of referring stylesheet.
|
||||
let parentSheet = sheet.parentStyleSheet;
|
||||
if (parentSheet && parentSheet.cssRules &&
|
||||
parentSheet.cssRules[0].type == Ci.nsIDOMCSSRule.CHARSET_RULE) {
|
||||
return this._convertToUnicode(aString,
|
||||
parentSheet.cssRules[0].encoding);
|
||||
}
|
||||
|
||||
// step 4 (2 of 2): charset of referring document.
|
||||
if (sheet.ownerNode && sheet.ownerNode.ownerDocument.characterSet) {
|
||||
return this._convertToUnicode(aString,
|
||||
sheet.ownerNode.ownerDocument.characterSet);
|
||||
}
|
||||
}
|
||||
|
||||
// step 5: default to utf-8.
|
||||
return this._convertToUnicode(aString, "UTF-8");
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert a given string, encoded in a given character set, to unicode.
|
||||
* @param string aString
|
||||
* A string.
|
||||
* @param string aCharset
|
||||
* A character set.
|
||||
* @return string
|
||||
* A unicode string.
|
||||
*/
|
||||
_convertToUnicode: function SE__convertToUnicode(aString, aCharset) {
|
||||
// Decoding primitives.
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
|
||||
try {
|
||||
converter.charset = aCharset;
|
||||
return converter.ConvertToUnicode(aString);
|
||||
} catch(e) {
|
||||
return aString;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load source from a file or file-like resource.
|
||||
*
|
||||
@ -790,6 +871,7 @@ StyleEditor.prototype = {
|
||||
{
|
||||
let channel = Services.io.newChannel(aHref, null, null);
|
||||
let chunks = [];
|
||||
let channelCharset = "";
|
||||
let streamListener = { // nsIStreamListener inherits nsIRequestObserver
|
||||
onStartRequest: function (aRequest, aContext, aStatusCode) {
|
||||
if (!Components.isSuccessCode(aStatusCode)) {
|
||||
@ -797,6 +879,10 @@ StyleEditor.prototype = {
|
||||
}
|
||||
}.bind(this),
|
||||
onDataAvailable: function (aRequest, aContext, aStream, aOffset, aCount) {
|
||||
let channel = aRequest.QueryInterface(Ci.nsIChannel);
|
||||
if (!channelCharset) {
|
||||
channelCharset = channel.contentCharset;
|
||||
}
|
||||
chunks.push(NetUtil.readInputStreamToString(aStream, aCount));
|
||||
},
|
||||
onStopRequest: function (aRequest, aContext, aStatusCode) {
|
||||
@ -804,7 +890,7 @@ StyleEditor.prototype = {
|
||||
return this._signalError(LOAD_ERROR);
|
||||
}
|
||||
|
||||
this._onSourceLoad(chunks.join(""));
|
||||
this._onSourceLoad(chunks.join(""), channelCharset);
|
||||
}.bind(this)
|
||||
};
|
||||
|
||||
@ -816,9 +902,14 @@ StyleEditor.prototype = {
|
||||
* Called when source has been loaded.
|
||||
*
|
||||
* @param string aSourceText
|
||||
* @param string aCharset
|
||||
* Optional. The character set to use. The default is to detect the
|
||||
* character set following the standard (see
|
||||
* <http://www.w3.org/TR/CSS2/syndata.html#charset>).
|
||||
*/
|
||||
_onSourceLoad: function SE__onSourceLoad(aSourceText)
|
||||
_onSourceLoad: function SE__onSourceLoad(aSourceText, aCharset)
|
||||
{
|
||||
aSourceText = this._decodeCSSCharset(aSourceText, aCharset || "");
|
||||
this._restoreExpando();
|
||||
this._state.text = prettifyCSS(aSourceText);
|
||||
this._loaded = true;
|
||||
|
@ -71,6 +71,10 @@ function testEditorAdded(aChrome, aEditor)
|
||||
|
||||
function testFirstStyleSheetEditor(aChrome, aEditor)
|
||||
{
|
||||
// Note: the html <link> contains charset="UTF-8".
|
||||
ok(aEditor._state.text.indexOf("\u263a") >= 0,
|
||||
"stylesheet is unicode-aware.");
|
||||
|
||||
//testing TESTCASE's simple.css stylesheet
|
||||
is(aEditor.styleSheetIndex, 0,
|
||||
"first stylesheet is at index 0");
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* ☺ */
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
|
@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>simple testcase</title>
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="simple.css"/>
|
||||
<link rel="stylesheet" charset="UTF-8" type="text/css" media="screen" href="simple.css"/>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: white;
|
||||
|
@ -7,7 +7,7 @@ let doc;
|
||||
let contentWindow;
|
||||
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/Services.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/Services.jsm", tempScope);
|
||||
let Services = tempScope.Services;
|
||||
|
||||
function createDocument()
|
||||
|
@ -6,7 +6,7 @@
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/devtools/CssLogic.jsm", tempScope);
|
||||
Cu.import("resource:///modules/devtools/CssHtmlTree.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/HUDService.jsm", tempScope);
|
||||
Cu.import("resource:///modules/HUDService.jsm", tempScope);
|
||||
let HUDService = tempScope.HUDService;
|
||||
let ConsoleUtils = tempScope.ConsoleUtils;
|
||||
let CssLogic = tempScope.CssLogic;
|
||||
|
@ -48,12 +48,14 @@ function testMenuFilterButton(aCategory) {
|
||||
menuItem = firstMenuItem;
|
||||
let prefKey;
|
||||
while (menuItem) {
|
||||
prefKey = menuItem.getAttribute("prefKey");
|
||||
chooseMenuItem(menuItem);
|
||||
ok(isChecked(menuItem), "menu item " + prefKey + " for category " +
|
||||
aCategory + " is checked after clicking it");
|
||||
ok(hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"on after clicking the appropriate menu item");
|
||||
if (menuItem.hasAttribute("prefKey")) {
|
||||
prefKey = menuItem.getAttribute("prefKey");
|
||||
chooseMenuItem(menuItem);
|
||||
ok(isChecked(menuItem), "menu item " + prefKey + " for category " +
|
||||
aCategory + " is checked after clicking it");
|
||||
ok(hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"on after clicking the appropriate menu item");
|
||||
}
|
||||
menuItem = menuItem.nextSibling;
|
||||
}
|
||||
ok(isChecked(button), "the button for category " + aCategory + " is " +
|
||||
@ -103,11 +105,13 @@ function testMenuFilterButton(aCategory) {
|
||||
|
||||
menuItem = firstMenuItem;
|
||||
while (menuItem) {
|
||||
let prefKey = menuItem.getAttribute("prefKey");
|
||||
ok(isChecked(menuItem), "menu item " + prefKey + " for category " +
|
||||
aCategory + " is checked after clicking the button");
|
||||
ok(hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"on after clicking the button");
|
||||
if (menuItem.hasAttribute("prefKey")) {
|
||||
let prefKey = menuItem.getAttribute("prefKey");
|
||||
ok(isChecked(menuItem), "menu item " + prefKey + " for category " +
|
||||
aCategory + " is checked after clicking the button");
|
||||
ok(hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"on after clicking the button");
|
||||
}
|
||||
menuItem = menuItem.nextSibling;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
let menuitems = [], menupopups = [], huds = [], tabs = [];
|
||||
let menuitems = [], menupopups = [], huds = [], tabs = [], runCount = 0;
|
||||
|
||||
function test()
|
||||
{
|
||||
@ -43,13 +43,18 @@ function test()
|
||||
function startTest()
|
||||
{
|
||||
// Find the relevant elements in the Web Console of tab 2.
|
||||
let win2 = tabs[1].linkedBrowser.contentWindow;
|
||||
let win2 = tabs[runCount*2 + 1].linkedBrowser.contentWindow;
|
||||
let hudId2 = HUDService.getHudIdByWindow(win2);
|
||||
huds[1] = HUDService.hudReferences[hudId2];
|
||||
HUDService.disableAnimation(hudId2);
|
||||
|
||||
menuitems[1] = huds[1].ui.rootElement.querySelector("#saveBodies");
|
||||
menupopups[1] = huds[1].ui.rootElement.querySelector("menupopup");
|
||||
if (runCount == 0) {
|
||||
menuitems[1] = huds[1].ui.rootElement.querySelector("#saveBodies");
|
||||
}
|
||||
else {
|
||||
menuitems[1] = huds[1].ui.rootElement.querySelector("#saveBodiesContextMenu");
|
||||
}
|
||||
menupopups[1] = menuitems[1].parentNode;
|
||||
|
||||
// Open the context menu from tab 2.
|
||||
menupopups[1].addEventListener("popupshown", onpopupshown2, false);
|
||||
@ -95,10 +100,10 @@ function onpopupshown2b(aEvent)
|
||||
menupopups[1].removeEventListener(aEvent.type, _onhidden, false);
|
||||
|
||||
// Switch to tab 1 and open the Web Console context menu from there.
|
||||
gBrowser.selectedTab = tabs[0];
|
||||
gBrowser.selectedTab = tabs[runCount*2];
|
||||
waitForFocus(function() {
|
||||
// Find the relevant elements in the Web Console of tab 1.
|
||||
let win1 = tabs[0].linkedBrowser.contentWindow;
|
||||
let win1 = tabs[runCount*2].linkedBrowser.contentWindow;
|
||||
let hudId1 = HUDService.getHudIdByWindow(win1);
|
||||
huds[0] = HUDService.hudReferences[hudId1];
|
||||
HUDService.disableAnimation(hudId1);
|
||||
@ -111,7 +116,7 @@ function onpopupshown2b(aEvent)
|
||||
|
||||
menupopups[0].addEventListener("popupshown", onpopupshown1, false);
|
||||
menupopups[0].openPopup();
|
||||
}, tabs[0].linkedBrowser.contentWindow);
|
||||
}, tabs[runCount*2].linkedBrowser.contentWindow);
|
||||
}, false);
|
||||
|
||||
executeSoon(function() {
|
||||
@ -134,12 +139,12 @@ function onpopupshown1(aEvent)
|
||||
menupopups[0].addEventListener("popuphidden", function _onhidden(aEvent) {
|
||||
menupopups[0].removeEventListener(aEvent.type, _onhidden, false);
|
||||
|
||||
gBrowser.selectedTab = tabs[1];
|
||||
gBrowser.selectedTab = tabs[runCount*2 + 1];
|
||||
waitForFocus(function() {
|
||||
// Reopen the context menu from tab 2.
|
||||
menupopups[1].addEventListener("popupshown", onpopupshown2c, false);
|
||||
menupopups[1].openPopup();
|
||||
}, tabs[1].linkedBrowser.contentWindow);
|
||||
}, tabs[runCount*2 + 1].linkedBrowser.contentWindow);
|
||||
}, false);
|
||||
|
||||
executeSoon(function() {
|
||||
@ -156,12 +161,25 @@ function onpopupshown2c(aEvent)
|
||||
menupopups[1].addEventListener("popuphidden", function _onhidden(aEvent) {
|
||||
menupopups[1].removeEventListener(aEvent.type, _onhidden, false);
|
||||
|
||||
// Done!
|
||||
huds = menuitems = menupopups = tabs = null;
|
||||
// Done if on second run
|
||||
closeConsole(gBrowser.selectedTab, function() {
|
||||
gBrowser.removeCurrentTab();
|
||||
executeSoon(finishTest);
|
||||
if (runCount == 0) {
|
||||
runCount++;
|
||||
executeSoon(test);
|
||||
}
|
||||
else {
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.selectedTab = tabs[2];
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.selectedTab = tabs[1];
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.selectedTab = tabs[0];
|
||||
gBrowser.removeCurrentTab();
|
||||
huds = menuitems = menupopups = tabs = null;
|
||||
executeSoon(finishTest);
|
||||
}
|
||||
});
|
||||
|
||||
}, false);
|
||||
|
||||
executeSoon(function() {
|
||||
|
@ -343,11 +343,30 @@ WebConsoleFrame.prototype = {
|
||||
this.saveRequestAndResponseBodies = !this.saveRequestAndResponseBodies;
|
||||
}.bind(this));
|
||||
saveBodies.setAttribute("checked", this.saveRequestAndResponseBodies);
|
||||
saveBodies.disabled = !this.getFilterState("networkinfo") &&
|
||||
!this.getFilterState("network");
|
||||
|
||||
let contextMenuId = this.outputNode.getAttribute("context");
|
||||
let contextMenu = doc.getElementById(contextMenuId);
|
||||
contextMenu.addEventListener("popupshowing", function() {
|
||||
saveBodies.parentNode.addEventListener("popupshowing", function() {
|
||||
saveBodies.setAttribute("checked", this.saveRequestAndResponseBodies);
|
||||
saveBodies.disabled = !this.getFilterState("networkinfo") &&
|
||||
!this.getFilterState("network");
|
||||
}.bind(this));
|
||||
|
||||
// Remove this part when context menu entry is removed.
|
||||
let saveBodiesContextMenu = doc.getElementById("saveBodiesContextMenu");
|
||||
saveBodiesContextMenu.addEventListener("command", function() {
|
||||
this.saveRequestAndResponseBodies = !this.saveRequestAndResponseBodies;
|
||||
}.bind(this));
|
||||
saveBodiesContextMenu.setAttribute("checked",
|
||||
this.saveRequestAndResponseBodies);
|
||||
saveBodiesContextMenu.disabled = !this.getFilterState("networkinfo") &&
|
||||
!this.getFilterState("network");
|
||||
|
||||
saveBodiesContextMenu.parentNode.addEventListener("popupshowing", function() {
|
||||
saveBodiesContextMenu.setAttribute("checked",
|
||||
this.saveRequestAndResponseBodies);
|
||||
saveBodiesContextMenu.disabled = !this.getFilterState("networkinfo") &&
|
||||
!this.getFilterState("network");
|
||||
}.bind(this));
|
||||
|
||||
this.closeButton = doc.getElementById("webconsole-close-button");
|
||||
@ -686,13 +705,22 @@ WebConsoleFrame.prototype = {
|
||||
let prefKey = target.getAttribute("prefKey");
|
||||
this.setFilterState(prefKey, state);
|
||||
|
||||
// Disable the log response and request body if network logging is off.
|
||||
if (prefKey == "networkinfo" || prefKey == "network") {
|
||||
let checkState = !this.getFilterState("networkinfo") &&
|
||||
!this.getFilterState("network");
|
||||
this.document.getElementById("saveBodies").disabled = checkState;
|
||||
this.document.getElementById("saveBodiesContextMenu").disabled = checkState;
|
||||
}
|
||||
|
||||
// Adjust the state of the button appropriately.
|
||||
let menuPopup = target.parentNode;
|
||||
|
||||
let someChecked = false;
|
||||
let menuItem = menuPopup.firstChild;
|
||||
while (menuItem) {
|
||||
if (menuItem.getAttribute("checked") === "true") {
|
||||
if (menuItem.hasAttribute("prefKey") &&
|
||||
menuItem.getAttribute("checked") === "true") {
|
||||
someChecked = true;
|
||||
break;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
<popupset id="mainPopupSet">
|
||||
<menupopup id="output-contextmenu">
|
||||
<menuitem id="saveBodies" type="checkbox" label="&saveBodies.label;"
|
||||
<menuitem id="saveBodiesContextMenu" type="checkbox" label="&saveBodies.label;"
|
||||
accesskey="&saveBodies.accesskey;"/>
|
||||
<menuitem id="menu_copy"/>
|
||||
<menuitem id="menu_selectAll"/>
|
||||
@ -63,6 +63,9 @@
|
||||
prefKey="network"/>
|
||||
<menuitem label="&btnConsoleLog;" type="checkbox" autocheck="false"
|
||||
prefKey="networkinfo"/>
|
||||
<menuseparator id="saveBodiesSeparator" />
|
||||
<menuitem id="saveBodies" type="checkbox" label="&saveBodies.label;"
|
||||
accesskey="&saveBodies.accesskey;"/>
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
<toolbarbutton label="&btnPageCSS.label;" type="menu-button"
|
||||
|
@ -36,6 +36,9 @@
|
||||
<!ENTITY openRecentMenu.label "Open Recent">
|
||||
<!ENTITY openRecentMenu.accesskey "R">
|
||||
|
||||
<!ENTITY revertCmd.label "Revert…">
|
||||
<!ENTITY revertCmd.accesskey "t">
|
||||
|
||||
<!ENTITY saveFileCmd.label "Save">
|
||||
<!ENTITY saveFileCmd.accesskey "S">
|
||||
<!ENTITY saveFileCmd.commandkey "s">
|
||||
|
@ -54,6 +54,14 @@ confirmClose=Do you want to save the changes you made to this scratchpad?
|
||||
# you try to close a scratchpad with unsaved changes.
|
||||
confirmClose.title=Unsaved Changes
|
||||
|
||||
# LOCALIZATION NOTE (confirmRevert): This is message in the prompt dialog when
|
||||
# you try to revert unsaved content of scratchpad.
|
||||
confirmRevert=Do you want to revert the changes you made to this scratchpad?
|
||||
|
||||
# LOCALIZATION NOTE (confirmRevert.title): This is title of the prompt dialog when
|
||||
# you try to revert unsaved content of scratchpad.
|
||||
confirmRevert.title=Revert Changes
|
||||
|
||||
# LOCALIZATION NOTE (scratchpadIntro): This is a multi-line comment explaining
|
||||
# how to use the Scratchpad. Note that this should be a valid JavaScript
|
||||
# comment inside /* and */.
|
||||
|
@ -2488,8 +2488,7 @@ html|*#gcli-output-frame {
|
||||
/* Responsive Mode */
|
||||
|
||||
.browserContainer[responsivemode] {
|
||||
background: #2a3643 url("chrome://browser/skin/devtools/responsive-background.png");
|
||||
box-shadow: 0 0 7px black inset;
|
||||
background: #222 url("chrome://browser/skin/devtools/responsive-background.png");
|
||||
padding: 0 20px 20px 20px;
|
||||
}
|
||||
|
||||
@ -2714,6 +2713,10 @@ html|*#gcli-output-frame {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.social-panel > .panel-arrowcontainer > .panel-arrowcontent {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.chat-status-icon {
|
||||
max-height: 16px;
|
||||
max-width: 16px;
|
||||
@ -2733,44 +2736,26 @@ html|*#gcli-output-frame {
|
||||
}
|
||||
|
||||
.chat-close-button {
|
||||
list-style-image: url("chrome://global/skin/icons/close.png");
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
.chat-close-button:hover {
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
list-style-image: url('chrome://browser/skin/social/chat-close.png');
|
||||
-moz-image-region: rect(0, 14px, 14px, 0);
|
||||
}
|
||||
|
||||
.chat-close-button:hover:active {
|
||||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
-moz-image-region: rect(14px, 14px, 28px, 0);
|
||||
}
|
||||
|
||||
|
||||
.chat-toggle-button {
|
||||
/* XXX get a real image for this */
|
||||
list-style-image: url("chrome://global/skin/icons/checkbox.png");
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
}
|
||||
|
||||
.chat-toggle-button:hover {
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
.chat-toggle-button[minimized="true"] {
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
.chat-toggle-button[minimized="true"]:hover {
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
.chat-close-button:hover {
|
||||
-moz-image-region: rect(28px, 14px, 42px, 0);
|
||||
}
|
||||
|
||||
.chat-title {
|
||||
font-weight: bold;
|
||||
color: -moz-dialogtext;
|
||||
cursor: inherit;
|
||||
}
|
||||
|
||||
.chat-titlebar {
|
||||
background-image: linear-gradient(white, #ddd);
|
||||
background-color: #d9d9d9;
|
||||
height: 20px;
|
||||
min-height: 20px;
|
||||
width: 100%;
|
||||
@ -2778,12 +2763,17 @@ html|*#gcli-output-frame {
|
||||
padding: 2px;
|
||||
border: none;
|
||||
border-bottom: 1px solid gray;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.chat-titlebar[minimized="true"] {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.chat-titlebar[selected] {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.chat-frame {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
@ -2791,7 +2781,7 @@ html|*#gcli-output-frame {
|
||||
}
|
||||
|
||||
.chatbar-button {
|
||||
/* XXX get a real image for this */
|
||||
background-color: #d9d9d9;
|
||||
list-style-image: url("chrome://browser/skin/social/social.png");
|
||||
border: none;
|
||||
margin: 0;
|
||||
@ -2804,6 +2794,7 @@ html|*#gcli-output-frame {
|
||||
|
||||
.chatbar-button[open="true"],
|
||||
.chatbar-button:active:hover {
|
||||
background-color: #f0f0f0;
|
||||
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,8 @@ browser.jar:
|
||||
skin/classic/browser/preferences/in-content/preferences.css (preferences/in-content/preferences.css)
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/social/social.png (social/social.png)
|
||||
skin/classic/browser/social/chat-close.png (social/chat-close.png)
|
||||
skin/classic/browser/tabbrowser/alltabs.png (tabbrowser/alltabs.png)
|
||||
skin/classic/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
|
||||
skin/classic/browser/tabbrowser/loading.png (tabbrowser/loading.png)
|
||||
|
BIN
browser/themes/gnomestripe/social/chat-close.png
Normal file
BIN
browser/themes/gnomestripe/social/chat-close.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 405 B |
BIN
browser/themes/gnomestripe/social/social.png
Normal file
BIN
browser/themes/gnomestripe/social/social.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
@ -3206,8 +3206,7 @@ html|*#gcli-output-frame {
|
||||
/* Responsive Mode */
|
||||
|
||||
.browserContainer[responsivemode] {
|
||||
background: #2a3643 url("chrome://browser/skin/devtools/responsive-background.png");
|
||||
box-shadow: 0 0 7px black inset;
|
||||
background: #222 url("chrome://browser/skin/devtools/responsive-background.png");
|
||||
padding: 0 20px 20px 20px;
|
||||
}
|
||||
|
||||
@ -3398,6 +3397,15 @@ html|*#gcli-output-frame {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.social-panel > .panel-arrowcontainer > .panel-arrowcontent {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#social-notification-box,
|
||||
.social-panel-frame {
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
/* === end of social toolbar provider menu === */
|
||||
|
||||
.chat-status-icon {
|
||||
@ -3419,44 +3427,26 @@ html|*#gcli-output-frame {
|
||||
}
|
||||
|
||||
.chat-close-button {
|
||||
list-style-image: url("chrome://global/skin/icons/close.png");
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
.chat-close-button:hover {
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
list-style-image: url('chrome://browser/skin/social/chat-close.png');
|
||||
-moz-image-region: rect(0, 14px, 14px, 0);
|
||||
}
|
||||
|
||||
.chat-close-button:hover:active {
|
||||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
-moz-image-region: rect(14px, 14px, 28px, 0);
|
||||
}
|
||||
|
||||
|
||||
.chat-toggle-button {
|
||||
/* XXX get a real image for this */
|
||||
list-style-image: url("chrome://global/skin/icons/checkbox.png");
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
}
|
||||
|
||||
.chat-toggle-button:hover {
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
.chat-toggle-button[minimized="true"] {
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
.chat-toggle-button[minimized="true"]:hover {
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
.chat-close-button:hover {
|
||||
-moz-image-region: rect(28px, 14px, 42px, 0);
|
||||
}
|
||||
|
||||
.chat-title {
|
||||
font-weight: bold;
|
||||
color: -moz-dialogtext;
|
||||
cursor: inherit;
|
||||
}
|
||||
|
||||
.chat-titlebar {
|
||||
background-image: linear-gradient(white, #ddd);
|
||||
background-color: #d9d9d9;
|
||||
height: 20px;
|
||||
min-height: 20px;
|
||||
width: 100%;
|
||||
@ -3464,12 +3454,17 @@ html|*#gcli-output-frame {
|
||||
padding: 2px;
|
||||
border: none;
|
||||
border-bottom: 1px solid #404040;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.chat-titlebar[minimized="true"] {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.chat-titlebar[selected] {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.chat-frame {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
@ -3477,8 +3472,7 @@ html|*#gcli-output-frame {
|
||||
}
|
||||
|
||||
.chatbar-button {
|
||||
/* XXX get a real image for this */
|
||||
background-image: linear-gradient(white, #ddd);
|
||||
background-color: #d9d9d9;
|
||||
list-style-image: url("chrome://browser/skin/social/social.png");
|
||||
border: none;
|
||||
margin: 0;
|
||||
@ -3491,6 +3485,7 @@ html|*#gcli-output-frame {
|
||||
|
||||
.chatbar-button[open="true"],
|
||||
.chatbar-button:active:hover {
|
||||
background-color: #f0f0f0;
|
||||
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
|
@ -108,6 +108,7 @@ browser.jar:
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/social/social.png (social/social.png)
|
||||
skin/classic/browser/social/chat-close.png (social/chat-close.png)
|
||||
skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon.png (tabbrowser/alltabs-box-bkgnd-icon.png)
|
||||
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
|
||||
skin/classic/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
|
||||
|
BIN
browser/themes/pinstripe/social/chat-close.png
Normal file
BIN
browser/themes/pinstripe/social/chat-close.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 405 B |
@ -3168,8 +3168,7 @@ html|*#gcli-output-frame {
|
||||
/* Responsive Mode */
|
||||
|
||||
.browserContainer[responsivemode] {
|
||||
background: #2a3643 url("chrome://browser/skin/devtools/responsive-background.png");
|
||||
box-shadow: 0 0 7px black inset;
|
||||
background: #222 url("chrome://browser/skin/devtools/responsive-background.png");
|
||||
padding: 0 20px 20px 20px;
|
||||
}
|
||||
|
||||
@ -3417,6 +3416,15 @@ html|*#gcli-output-frame {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.social-panel > .panel-arrowcontainer > .panel-arrowcontent {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#social-notification-box,
|
||||
.social-panel-frame {
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
.chat-status-icon {
|
||||
max-height: 16px;
|
||||
max-width: 16px;
|
||||
@ -3436,43 +3444,26 @@ html|*#gcli-output-frame {
|
||||
}
|
||||
|
||||
.chat-close-button {
|
||||
list-style-image: url("chrome://global/skin/icons/Close.gif");
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
.chat-close-button:hover {
|
||||
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
|
||||
list-style-image: url('chrome://browser/skin/social/chat-close.png');
|
||||
-moz-image-region: rect(0, 14px, 14px, 0);
|
||||
}
|
||||
|
||||
.chat-close-button:hover:active {
|
||||
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
|
||||
-moz-image-region: rect(14px, 14px, 28px, 0);
|
||||
}
|
||||
|
||||
|
||||
.chat-toggle-button {
|
||||
/* XXX get a real image for this */
|
||||
list-style-image: url("chrome://global/skin/icons/expand.png");
|
||||
}
|
||||
|
||||
.chat-toggle-button:hover {
|
||||
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
.chat-toggle-button[minimized="true"] {
|
||||
list-style-image: url("chrome://global/skin/icons/collapse.png");
|
||||
}
|
||||
|
||||
.chat-toggle-button[minimized="true"]:hover {
|
||||
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
|
||||
.chat-close-button:hover {
|
||||
-moz-image-region: rect(28px, 14px, 42px, 0);
|
||||
}
|
||||
|
||||
.chat-title {
|
||||
font-weight: bold;
|
||||
color: -moz-dialogtext;
|
||||
cursor: inherit;
|
||||
}
|
||||
|
||||
.chat-titlebar {
|
||||
background-image: linear-gradient(white, #ddd);
|
||||
background-color: #c4cfde;
|
||||
height: 20px;
|
||||
min-height: 20px;
|
||||
width: 100%;
|
||||
@ -3480,12 +3471,17 @@ html|*#gcli-output-frame {
|
||||
padding: 2px;
|
||||
border: none;
|
||||
border-bottom: 1px solid gray;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.chat-titlebar[minimized="true"] {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.chat-titlebar[selected] {
|
||||
background-color: #dae3f0;
|
||||
}
|
||||
|
||||
.chat-frame {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
@ -3496,7 +3492,7 @@ html|*#gcli-output-frame {
|
||||
/* XXX get a real image for this */
|
||||
-moz-appearance: none;
|
||||
list-style-image: url("chrome://browser/skin/social/social.png");
|
||||
background-image: linear-gradient(white, #ddd);
|
||||
background-color: #c4cfde;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
@ -3515,6 +3511,7 @@ html|*#gcli-output-frame {
|
||||
.chatbar-button[open="true"],
|
||||
.chatbar-button:hover,
|
||||
.chatbar-button:active:hover {
|
||||
background-color: #dae3f0;
|
||||
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
|
@ -105,6 +105,7 @@ browser.jar:
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/social/social.png (social/social.png)
|
||||
skin/classic/browser/social/chat-close.png (social/chat-close.png)
|
||||
skin/classic/browser/tabbrowser/alltabs.png (tabbrowser/alltabs.png)
|
||||
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
|
||||
skin/classic/browser/tabbrowser/newtab-inverted.png (tabbrowser/newtab-inverted.png)
|
||||
@ -307,6 +308,7 @@ browser.jar:
|
||||
skin/classic/aero/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/aero/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/aero/browser/social/social.png (social/social.png)
|
||||
skin/classic/aero/browser/social/chat-close.png (social/chat-close.png)
|
||||
skin/classic/aero/browser/tabbrowser/alltabs.png (tabbrowser/alltabs.png)
|
||||
skin/classic/aero/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
|
||||
skin/classic/aero/browser/tabbrowser/newtab-inverted.png (tabbrowser/newtab-inverted.png)
|
||||
|
BIN
browser/themes/winstripe/social/chat-close.png
Normal file
BIN
browser/themes/winstripe/social/chat-close.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 419 B |
@ -34,17 +34,13 @@ case "$target" in
|
||||
fi
|
||||
;;
|
||||
*-darwin*)
|
||||
# we prefer gcc-4.2 over gcc on older darwin, so
|
||||
# use that specific version if it's available.
|
||||
# On newer versions of darwin, gcc is llvm-gcc while gcc-4.2 is the plain
|
||||
# one, so we also try that first. If that fails, we fall back to clang
|
||||
# as llvm-gcc is an unsupported dead end.
|
||||
MOZ_PATH_PROGS(CC, $CC gcc-4.2 clang gcc)
|
||||
MOZ_PATH_PROGS(CXX, $CXX g++-4.2 clang++ g++)
|
||||
IS_LLVM_GCC=$($CC -v 2>&1 | grep llvm-gcc)
|
||||
if test -n "$IS_LLVM_GCC"
|
||||
# GCC on darwin is based on gcc 4.2 and we don't support it anymore.
|
||||
MOZ_PATH_PROGS(CC, $CC clang)
|
||||
MOZ_PATH_PROGS(CXX, $CXX clang++)
|
||||
IS_GCC=$($CC -v 2>&1 | grep gcc)
|
||||
if test -n "$IS_GCC"
|
||||
then
|
||||
echo llvm-gcc is known to be broken, please use gcc-4.2 or clang.
|
||||
echo gcc is known to be broken on OS X, please use clang.
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
@ -1,56 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import devicemanager
|
||||
import sys
|
||||
import os
|
||||
|
||||
def copy(dm, gre_path):
|
||||
file = sys.argv[2]
|
||||
if len(sys.argv) >= 4:
|
||||
path = sys.argv[3]
|
||||
else:
|
||||
path = gre_path
|
||||
if os.path.isdir(file):
|
||||
dm.pushDir(file, path.replace('\\','/'))
|
||||
else:
|
||||
dm.pushFile(file, path.replace('\\','/'))
|
||||
|
||||
def delete(dm, gre_path):
|
||||
file = sys.argv[2]
|
||||
dm.removeFile(file)
|
||||
|
||||
def main():
|
||||
ip_addr = os.environ.get("DEVICE_IP")
|
||||
port = os.environ.get("DEVICE_PORT")
|
||||
gre_path = os.environ.get("REMOTE_GRE_PATH").replace('\\','/')
|
||||
|
||||
if ip_addr == None:
|
||||
print "Error: please define the environment variable DEVICE_IP before running this test"
|
||||
sys.exit(1)
|
||||
|
||||
if port == None:
|
||||
print "Error: please define the environment variable DEVICE_PORT before running this test"
|
||||
sys.exit(1)
|
||||
|
||||
if gre_path == None:
|
||||
print "Error: please define the environment variable REMOTE_GRE_PATH before running this test"
|
||||
sys.exit(1)
|
||||
|
||||
dm = devicemanager.DeviceManager(ip_addr, int(port))
|
||||
dm.sendCMD(['cd '+ gre_path], sleep = 1)
|
||||
dm.debug = 0
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print "usage: python devicemanager-utils.py <cmd> <path> [arg]"
|
||||
cmd = sys.argv[1]
|
||||
if (cmd == 'copy'):
|
||||
sys.exit(copy(dm, gre_path))
|
||||
if (cmd == 'delete'):
|
||||
sys.exit(delete(dm, gre_path))
|
||||
print "unrecognized command. supported commands are copy and delete"
|
||||
sys.exit(-1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -17,8 +17,7 @@
|
||||
</activity>
|
||||
<receiver android:name=".SUTStartupIntentReceiver">
|
||||
<intent-filter>
|
||||
<action android:value="android.intent.action.BOOT_COMPLETED" android:name="android.intent.action.BOOT_COMPLETED"/>
|
||||
<category android:value="android.intent.category.HOME" android:name="android.intent.category.HOME"/>
|
||||
<action android:name="android.intent.action.MEDIA_MOUNTED"></action>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<service android:name=".service.ASMozStub">
|
||||
@ -58,4 +57,4 @@
|
||||
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"></uses-permission>
|
||||
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"></uses-permission>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
@ -191,9 +191,15 @@ public class WatcherService extends Service
|
||||
|
||||
private void handleCommand(Intent intent)
|
||||
{
|
||||
String sCmd = intent.getStringExtra("command");
|
||||
// Note: intent can be null "if the service is being restarted after its process
|
||||
// has gone away". In this case, we will consider that to be equivalent to a start
|
||||
// http://developer.android.com/reference/android/app/Service.html#onStartCommand%28android.content.Intent,%20int,%20int%29
|
||||
|
||||
// Debug.waitForDebugger();
|
||||
String sCmd = "start";
|
||||
if (intent != null)
|
||||
{
|
||||
sCmd = intent.getStringExtra("command");
|
||||
}
|
||||
|
||||
if (sCmd != null)
|
||||
{
|
||||
|
@ -264,8 +264,8 @@ class PythonJob(Job):
|
||||
pass # sys.exit(0) is not a failure
|
||||
else:
|
||||
print >>sys.stderr, e
|
||||
print >>sys.stderr, traceback.print_exc()
|
||||
return (e.code if isinstance(e.code, int) else 1)
|
||||
traceback.print_exc()
|
||||
return -127
|
||||
finally:
|
||||
os.environ.clear()
|
||||
os.environ.update(oldenv)
|
||||
|
9
build/pymake/tests/native-command-raise.mk
Normal file
9
build/pymake/tests/native-command-raise.mk
Normal file
@ -0,0 +1,9 @@
|
||||
#T gmake skip
|
||||
#T returncode: 2
|
||||
#T grep-for: "Exception: info-exception"
|
||||
|
||||
CMD = %pycmd asplode_raise
|
||||
PYCOMMANDPATH = $(TESTPATH) $(TESTPATH)/subdir
|
||||
|
||||
all:
|
||||
@$(CMD) info-exception
|
@ -30,3 +30,6 @@ def asplode(args):
|
||||
def asplode_return(args):
|
||||
arg0 = convertasplode(args[0])
|
||||
return arg0
|
||||
|
||||
def asplode_raise(args):
|
||||
raise Exception(args[0])
|
||||
|
@ -392,7 +392,7 @@ private:
|
||||
static JSBool
|
||||
CheckObjectAccess(JSContext *cx, JSHandleObject obj,
|
||||
JSHandleId id, JSAccessMode mode,
|
||||
jsval *vp);
|
||||
JSMutableHandleValue vp);
|
||||
|
||||
// Decides, based on CSP, whether or not eval() and stuff can be executed.
|
||||
static JSBool
|
||||
|
@ -532,7 +532,7 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
|
||||
JSBool
|
||||
nsScriptSecurityManager::CheckObjectAccess(JSContext *cx, JSHandleObject obj,
|
||||
JSHandleId id, JSAccessMode mode,
|
||||
jsval *vp)
|
||||
JSMutableHandleValue vp)
|
||||
{
|
||||
// Get the security manager
|
||||
nsScriptSecurityManager *ssm =
|
||||
@ -548,9 +548,9 @@ nsScriptSecurityManager::CheckObjectAccess(JSContext *cx, JSHandleObject obj,
|
||||
// a different trust domain.
|
||||
// 2. A user-defined getter or setter function accessible on another
|
||||
// trust domain's window or document object.
|
||||
// *vp can be a primitive, in that case, we use obj as the target
|
||||
// vp can be a primitive, in that case, we use obj as the target
|
||||
// object.
|
||||
JSObject* target = JSVAL_IS_PRIMITIVE(*vp) ? obj : JSVAL_TO_OBJECT(*vp);
|
||||
JSObject* target = JSVAL_IS_PRIMITIVE(vp) ? obj : JSVAL_TO_OBJECT(vp);
|
||||
|
||||
// Do the same-origin check -- this sets a JS exception if the check fails.
|
||||
// Pass the parent object's class name, as we have no class-info for it.
|
||||
|
@ -86,9 +86,9 @@ nsChromeRegistry::LogMessageWithContext(nsIURI* aURL, uint32_t aLineNumber, uint
|
||||
if (aURL)
|
||||
aURL->GetSpec(spec);
|
||||
|
||||
rv = error->Init(NS_ConvertUTF8toUTF16(formatted).get(),
|
||||
NS_ConvertUTF8toUTF16(spec).get(),
|
||||
nullptr,
|
||||
rv = error->Init(NS_ConvertUTF8toUTF16(formatted),
|
||||
NS_ConvertUTF8toUTF16(spec),
|
||||
EmptyString(),
|
||||
aLineNumber, 0, flags, "chrome registration");
|
||||
PR_smprintf_free(formatted);
|
||||
|
||||
|
@ -152,6 +152,11 @@ if test -z "$PERL" -o "$PERL" = ":"; then
|
||||
AC_MSG_ERROR([perl not found in \$PATH])
|
||||
fi
|
||||
|
||||
AC_SUBST(GAIADIR)
|
||||
if test -n "$GAIADIR" ; then
|
||||
AC_DEFINE(PACKAGE_GAIA)
|
||||
fi
|
||||
|
||||
MOZ_ARG_WITH_STRING(gonk,
|
||||
[ --with-gonk=DIR
|
||||
location of gonk dir],
|
||||
|
@ -688,7 +688,7 @@ nsContentSink::ProcessLink(const nsSubstring& aAnchor, const nsSubstring& aHref,
|
||||
bool hasPrefetch = linkTypes & PREFETCH;
|
||||
// prefetch href if relation is "next" or "prefetch"
|
||||
if (hasPrefetch || (linkTypes & NEXT)) {
|
||||
PrefetchHref(aHref, nullptr, hasPrefetch);
|
||||
PrefetchHref(aHref, mDocument, hasPrefetch);
|
||||
}
|
||||
|
||||
if (!aHref.IsEmpty() && (linkTypes & DNS_PREFETCH)) {
|
||||
@ -795,7 +795,7 @@ nsContentSink::ProcessMETATag(nsIContent* aContent)
|
||||
|
||||
void
|
||||
nsContentSink::PrefetchHref(const nsAString &aHref,
|
||||
nsIContent *aSource,
|
||||
nsINode *aSource,
|
||||
bool aExplicit)
|
||||
{
|
||||
//
|
||||
|
@ -159,7 +159,7 @@ protected:
|
||||
const nsSubstring& aType,
|
||||
const nsSubstring& aMedia);
|
||||
|
||||
void PrefetchHref(const nsAString &aHref, nsIContent *aSource,
|
||||
void PrefetchHref(const nsAString &aHref, nsINode *aSource,
|
||||
bool aExplicit);
|
||||
|
||||
// aHref can either be the usual URI format or of the form "//www.hostname.com"
|
||||
|
@ -3260,9 +3260,9 @@ nsContentUtils::ReportToConsole(uint32_t aErrorFlags,
|
||||
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = errorObject->InitWithWindowID(errorText.get(),
|
||||
NS_ConvertUTF8toUTF16(spec).get(), // file name
|
||||
aSourceLine.get(),
|
||||
rv = errorObject->InitWithWindowID(errorText,
|
||||
NS_ConvertUTF8toUTF16(spec), // file name
|
||||
aSourceLine,
|
||||
aLineNumber, aColumnNumber,
|
||||
aErrorFlags, aCategory,
|
||||
innerWindowID);
|
||||
|
@ -1093,9 +1093,9 @@ nsEventSource::PrintErrorOnConsole(const char *aBundleURI,
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = errObj->InitWithWindowID(message.get(),
|
||||
mScriptFile.get(),
|
||||
nullptr,
|
||||
rv = errObj->InitWithWindowID(message,
|
||||
mScriptFile,
|
||||
EmptyString(),
|
||||
mScriptLine, 0,
|
||||
nsIScriptError::errorFlag,
|
||||
"Event Source", mInnerWindowID);
|
||||
|
@ -683,10 +683,10 @@ ContentScriptErrorReporter(JSContext* aCx,
|
||||
|
||||
if (aReport) {
|
||||
if (aReport->ucmessage) {
|
||||
message.Assign(reinterpret_cast<const PRUnichar*>(aReport->ucmessage));
|
||||
message.Assign(static_cast<const PRUnichar*>(aReport->ucmessage));
|
||||
}
|
||||
filename.AssignWithConversion(aReport->filename);
|
||||
line.Assign(reinterpret_cast<const PRUnichar*>(aReport->uclinebuf));
|
||||
line.Assign(static_cast<const PRUnichar*>(aReport->uclinebuf));
|
||||
lineNumber = aReport->lineno;
|
||||
columnNumber = aReport->uctokenptr - aReport->uclinebuf;
|
||||
flags = aReport->flags;
|
||||
@ -700,7 +700,7 @@ ContentScriptErrorReporter(JSContext* aCx,
|
||||
message.AssignWithConversion(aMessage);
|
||||
}
|
||||
|
||||
rv = scriptError->Init(message.get(), filename.get(), line.get(),
|
||||
rv = scriptError->Init(message, filename, line,
|
||||
lineNumber, columnNumber, flags,
|
||||
"Message manager content script");
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -731,7 +731,7 @@ ContentScriptErrorReporter(JSContext* aCx,
|
||||
error.AppendInt(lineNumber, 10);
|
||||
error.Append(": ");
|
||||
if (aReport->ucmessage) {
|
||||
AppendUTF16toUTF8(reinterpret_cast<const PRUnichar*>(aReport->ucmessage),
|
||||
AppendUTF16toUTF8(static_cast<const PRUnichar*>(aReport->ucmessage),
|
||||
error);
|
||||
} else {
|
||||
error.Append(aMessage);
|
||||
|
@ -1822,6 +1822,7 @@ GK_ATOM(svgTextFrame2, "SVGTextFrame2")
|
||||
GK_ATOM(svgTextPathFrame, "SVGTextPathFrame")
|
||||
GK_ATOM(svgTSpanFrame, "SVGTSpanFrame")
|
||||
GK_ATOM(svgUseFrame, "SVGUseFrame")
|
||||
GK_ATOM(svgViewFrame, "SVGViewFrame")
|
||||
GK_ATOM(HTMLVideoFrame, "VideoFrame")
|
||||
GK_ATOM(onloadend, "onloadend")
|
||||
GK_ATOM(onloadstart, "onloadstart")
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define nsPropertyTable_h_
|
||||
|
||||
#include "nscore.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
class nsIAtom;
|
||||
typedef PRUptrdiff PtrBits;
|
||||
|
@ -130,9 +130,9 @@ nsWebSocket::PrintErrorOnConsole(const char *aBundleURI,
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = errorObject->InitWithWindowID(message.get(),
|
||||
NS_ConvertUTF8toUTF16(mScriptFile).get(),
|
||||
nullptr, mScriptLine, 0,
|
||||
rv = errorObject->InitWithWindowID(message,
|
||||
NS_ConvertUTF8toUTF16(mScriptFile),
|
||||
EmptyString(), mScriptLine, 0,
|
||||
nsIScriptError::errorFlag, "Web Socket",
|
||||
mInnerWindowID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -350,7 +350,8 @@ nsXMLHttpRequest::nsXMLHttpRequest()
|
||||
mFirstStartRequestSeen(false),
|
||||
mInLoadProgressEvent(false),
|
||||
mResultJSON(JSVAL_VOID),
|
||||
mResultArrayBuffer(nullptr)
|
||||
mResultArrayBuffer(nullptr),
|
||||
mXPCOMifier(nullptr)
|
||||
{
|
||||
nsLayoutStatics::AddRef();
|
||||
|
||||
@ -3695,13 +3696,11 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
|
||||
// need to see these notifications for proper functioning.
|
||||
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
|
||||
mChannelEventSink = do_GetInterface(mNotificationCallbacks);
|
||||
*aResult = static_cast<nsIChannelEventSink*>(this);
|
||||
NS_ADDREF_THIS();
|
||||
*aResult = static_cast<nsIChannelEventSink*>(EnsureXPCOMifier().get());
|
||||
return NS_OK;
|
||||
} else if (aIID.Equals(NS_GET_IID(nsIProgressEventSink))) {
|
||||
mProgressEventSink = do_GetInterface(mNotificationCallbacks);
|
||||
*aResult = static_cast<nsIProgressEventSink*>(this);
|
||||
NS_ADDREF_THIS();
|
||||
*aResult = static_cast<nsIProgressEventSink*>(EnsureXPCOMifier().get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3742,7 +3741,21 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
|
||||
|
||||
return wwatch->GetPrompt(window, aIID,
|
||||
reinterpret_cast<void**>(aResult));
|
||||
|
||||
}
|
||||
// Now check for the various XHR non-DOM interfaces, except
|
||||
// nsIProgressEventSink and nsIChannelEventSink which we already
|
||||
// handled above.
|
||||
else if (aIID.Equals(NS_GET_IID(nsIStreamListener))) {
|
||||
*aResult = static_cast<nsIStreamListener*>(EnsureXPCOMifier().get());
|
||||
return NS_OK;
|
||||
}
|
||||
else if (aIID.Equals(NS_GET_IID(nsIRequestObserver))) {
|
||||
*aResult = static_cast<nsIRequestObserver*>(EnsureXPCOMifier().get());
|
||||
return NS_OK;
|
||||
}
|
||||
else if (aIID.Equals(NS_GET_IID(nsITimerCallback))) {
|
||||
*aResult = static_cast<nsITimerCallback*>(EnsureXPCOMifier().get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return QueryInterface(aIID, aResult);
|
||||
@ -3860,6 +3873,16 @@ nsXMLHttpRequest::StartProgressEventTimer()
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsXMLHttpRequestXPCOMifier>
|
||||
nsXMLHttpRequest::EnsureXPCOMifier()
|
||||
{
|
||||
if (!mXPCOMifier) {
|
||||
mXPCOMifier = new nsXMLHttpRequestXPCOMifier(this);
|
||||
}
|
||||
nsRefPtr<nsXMLHttpRequestXPCOMifier> newRef(mXPCOMifier);
|
||||
return newRef.forget();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXMLHttpRequest::nsHeaderVisitor, nsIHttpHeaderVisitor)
|
||||
|
||||
NS_IMETHODIMP nsXMLHttpRequest::
|
||||
@ -3957,3 +3980,47 @@ NS_IMETHODIMP nsXMLHttpProgressEvent::GetTotalSize(uint32_t *aTotalSize)
|
||||
LL_L2UI(*aTotalSize, mMaxProgress);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsXMLHttpRequestXPCOMifier implementation
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXMLHttpRequestXPCOMifier)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamListener)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXMLHttpRequestXPCOMifier)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXMLHttpRequestXPCOMifier)
|
||||
|
||||
// Can't NS_IMPL_CYCLE_COLLECTION_1 because mXHR has ambiguous
|
||||
// inheritance from nsISupports.
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttpRequestXPCOMifier)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLHttpRequestXPCOMifier)
|
||||
if (tmp->mXHR) {
|
||||
tmp->mXHR->mXPCOMifier = nullptr;
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mXHR)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXMLHttpRequestXPCOMifier)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mXHR, nsIXMLHttpRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXMLHttpRequestXPCOMifier::GetInterface(const nsIID & aIID, void **aResult)
|
||||
{
|
||||
// Return ourselves for the things we implement (except
|
||||
// nsIInterfaceRequestor) and the XHR for the rest.
|
||||
if (!aIID.Equals(NS_GET_IID(nsIInterfaceRequestor))) {
|
||||
nsresult rv = QueryInterface(aIID, aResult);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return mXHR->GetInterface(aIID, aResult);
|
||||
}
|
||||
|
@ -114,6 +114,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class nsXMLHttpRequestXPCOMifier;
|
||||
|
||||
// Make sure that any non-DOM interfaces added here are also added to
|
||||
// nsXMLHttpRequestXPCOMifier.
|
||||
class nsXMLHttpRequest : public nsXHREventTarget,
|
||||
public nsIXMLHttpRequest,
|
||||
public nsIJSXMLHttpRequest,
|
||||
@ -126,6 +130,8 @@ class nsXMLHttpRequest : public nsXHREventTarget,
|
||||
public nsITimerCallback
|
||||
{
|
||||
friend class nsXHRParseEndListener;
|
||||
friend class nsXMLHttpRequestXPCOMifier;
|
||||
|
||||
public:
|
||||
nsXMLHttpRequest();
|
||||
virtual ~nsXMLHttpRequest();
|
||||
@ -140,7 +146,7 @@ public:
|
||||
return GetOwner();
|
||||
}
|
||||
|
||||
// The WebIDL constructor.
|
||||
// The WebIDL constructors.
|
||||
static already_AddRefed<nsXMLHttpRequest>
|
||||
Constructor(JSContext* aCx,
|
||||
nsISupports* aGlobal,
|
||||
@ -160,6 +166,22 @@ public:
|
||||
return req.forget();
|
||||
}
|
||||
|
||||
static already_AddRefed<nsXMLHttpRequest>
|
||||
Constructor(JSContext* aCx,
|
||||
nsISupports* aGlobal,
|
||||
const nsAString& ignored,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// Pretend like someone passed null, so we can pick up the default values
|
||||
mozilla::dom::MozXMLHttpRequestParameters params;
|
||||
if (!params.Init(aCx, JS::NullValue())) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Constructor(aCx, aGlobal, params, aRv);
|
||||
}
|
||||
|
||||
void Construct(nsIPrincipal* aPrincipal,
|
||||
nsPIDOMWindow* aOwnerWindow,
|
||||
nsIURI* aBaseURI = NULL)
|
||||
@ -502,6 +524,8 @@ protected:
|
||||
const mozilla::dom::Optional<nsAString>& user,
|
||||
const mozilla::dom::Optional<nsAString>& password);
|
||||
|
||||
already_AddRefed<nsXMLHttpRequestXPCOMifier> EnsureXPCOMifier();
|
||||
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
@ -657,10 +681,49 @@ protected:
|
||||
nsCString value;
|
||||
};
|
||||
nsTArray<RequestHeader> mModifiedRequestHeaders;
|
||||
|
||||
// Helper object to manage our XPCOM scriptability bits
|
||||
nsXMLHttpRequestXPCOMifier* mXPCOMifier;
|
||||
};
|
||||
|
||||
#undef IMPL_EVENT_HANDLER
|
||||
|
||||
// A shim class designed to expose the non-DOM interfaces of
|
||||
// XMLHttpRequest via XPCOM stuff.
|
||||
class nsXMLHttpRequestXPCOMifier MOZ_FINAL : public nsIStreamListener,
|
||||
public nsIChannelEventSink,
|
||||
public nsIProgressEventSink,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsITimerCallback,
|
||||
public nsCycleCollectionParticipant
|
||||
{
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXMLHttpRequestXPCOMifier,
|
||||
nsIStreamListener)
|
||||
|
||||
nsXMLHttpRequestXPCOMifier(nsXMLHttpRequest* aXHR) :
|
||||
mXHR(aXHR)
|
||||
{
|
||||
}
|
||||
|
||||
~nsXMLHttpRequestXPCOMifier() {
|
||||
if (mXHR) {
|
||||
mXHR->mXPCOMifier = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NS_FORWARD_NSISTREAMLISTENER(mXHR->)
|
||||
NS_FORWARD_NSIREQUESTOBSERVER(mXHR->)
|
||||
NS_FORWARD_NSICHANNELEVENTSINK(mXHR->)
|
||||
NS_FORWARD_NSIPROGRESSEVENTSINK(mXHR->)
|
||||
NS_FORWARD_NSITIMERCALLBACK(mXHR->)
|
||||
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
private:
|
||||
nsRefPtr<nsXMLHttpRequest> mXHR;
|
||||
};
|
||||
|
||||
// helper class to expose a progress DOM Event
|
||||
|
||||
class nsXMLHttpProgressEvent : public nsIDOMProgressEvent,
|
||||
|
@ -44,6 +44,7 @@ MOCHITEST_CHROME_FILES = \
|
||||
test_bug752226-4.xul \
|
||||
test_bug682305.html \
|
||||
test_bug780199.xul \
|
||||
test_bug780529.xul \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
40
content/base/test/chrome/test_bug780529.xul
Normal file
40
content/base/test/chrome/test_bug780529.xul
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=780529
|
||||
-->
|
||||
<window title="Mozilla Bug 780529"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=780529"
|
||||
target="_blank">Mozilla Bug 780529</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
/** Test for Bug 780529 **/
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("GET", "", true);
|
||||
// Have to call send() to get the XHR hooked up as the notification callbacks
|
||||
req.send();
|
||||
var callbacks = req.channel.notificationCallbacks;
|
||||
var sink = callbacks.getInterface(Components.interfaces.nsIChannelEventSink);
|
||||
ok(sink instanceof Components.interfaces.nsIChannelEventSink,
|
||||
"Should be a channel event sink")
|
||||
ok("asyncOnChannelRedirect" in sink,
|
||||
"Should have the right methods for an event sink");
|
||||
|
||||
is(callbacks.getInterface(Components.interfaces.nsIXMLHttpRequest), req,
|
||||
"Should have the right object");
|
||||
sinkReq = sink.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
|
||||
isnot(sinkReq, callbacks, "Sink should not be the XHR object");
|
||||
is(sinkReq.getInterface(Components.interfaces.nsIXMLHttpRequest), req,
|
||||
"Should have the XHR object now");
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
@ -29,15 +29,15 @@ function runTests() {
|
||||
{mozAnon: 1},
|
||||
{mozAnon: []},
|
||||
{get mozAnon() { return true; }},
|
||||
];
|
||||
|
||||
let invalidParameters = [
|
||||
0,
|
||||
7,
|
||||
Math.PI,
|
||||
"string",
|
||||
true,
|
||||
false,
|
||||
];
|
||||
|
||||
let invalidParameters = [
|
||||
{get mozSystem() { throw "Bla"; } },
|
||||
];
|
||||
|
||||
|
@ -385,8 +385,6 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
// Get some prefs for some preferred/overriden things
|
||||
NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
|
||||
|
||||
bool forceOSMesa =
|
||||
Preferences::GetBool("webgl.force_osmesa", false);
|
||||
#ifdef XP_WIN
|
||||
bool preferEGL =
|
||||
Preferences::GetBool("webgl.prefer-egl", false);
|
||||
@ -507,16 +505,6 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
}
|
||||
#endif
|
||||
|
||||
// if we're forcing osmesa, do it first
|
||||
if (forceOSMesa) {
|
||||
gl = gl::GLContextProviderOSMesa::CreateOffscreen(gfxIntSize(width, height), format);
|
||||
if (!gl || !InitAndValidateGL()) {
|
||||
GenerateWarning("OSMesa forced, but creating context failed -- aborting!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
GenerateWarning("Using software rendering via OSMesa (THIS WILL BE SLOW)");
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
// if we want EGL, try it now
|
||||
if (!gl && (preferEGL || useANGLE) && !preferOpenGL) {
|
||||
@ -542,19 +530,6 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
}
|
||||
}
|
||||
|
||||
// finally, try OSMesa
|
||||
if (!gl) {
|
||||
gl = gl::GLContextProviderOSMesa::CreateOffscreen(gfxIntSize(width, height), format);
|
||||
if (gl) {
|
||||
if (!InitAndValidateGL()) {
|
||||
GenerateWarning("Error during OSMesa initialization");
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
GenerateWarning("Using software rendering via OSMesa (THIS WILL BE SLOW)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!gl) {
|
||||
GenerateWarning("Can't get a usable WebGL context");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -125,6 +125,7 @@ NS_IMPL_ELEMENT_CLONE(nsHTMLSharedListElement)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLSharedListElement, Compact, compact)
|
||||
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLSharedListElement, Start, start, 1)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLSharedListElement, Type, type)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLSharedListElement, Reversed, reversed)
|
||||
|
||||
// Shared with nsHTMLSharedElement.cpp
|
||||
nsAttrValue::EnumTable kListTypeTable[] = {
|
||||
|
@ -15,8 +15,11 @@
|
||||
|
||||
/** Test for HTMLOLElement attributes reflection **/
|
||||
|
||||
// TODO: .reversed (boolean), bug 601912
|
||||
todo("reversed" in document.createElement("ol"), "reversed is not yet implemented");
|
||||
// .reversed (boolean)
|
||||
reflectBoolean({
|
||||
element: document.createElement("ol"),
|
||||
attribute: "reversed",
|
||||
})
|
||||
|
||||
// .start
|
||||
reflectInt({
|
||||
|
@ -162,8 +162,6 @@ var gSnifferTests = [
|
||||
{ name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.233, size:28942 },
|
||||
{ name:"seek.webm", type:"video/webm", duration:3.966, size:215529 },
|
||||
{ name:"short.mp4", type:"video/mp4", duration:0.2, size:29435},
|
||||
// A mp3 file without id3 tags.
|
||||
{ name:"notags.mp3", type:"audio/mpeg", duration:0.28, size:2506},
|
||||
// A mp3 file with id3 tags.
|
||||
{ name:"id3tags.mp3", type:"audio/mpeg", duration:0.28, size:3530},
|
||||
{ name:"bogus.duh", type:"bogus/duh" }
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mozilla/dom/AudioContextBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(AudioContext, mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(AudioContext)
|
||||
@ -34,8 +35,7 @@ JSObject*
|
||||
AudioContext::WrapObject(JSContext* aCx, JSObject* aScope,
|
||||
bool* aTriedToWrap)
|
||||
{
|
||||
return dom::mozAudioContextBinding::Wrap(aCx, aScope, this,
|
||||
aTriedToWrap);
|
||||
return mozAudioContextBinding::Wrap(aCx, aScope, this, aTriedToWrap);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<AudioContext>
|
||||
@ -53,4 +53,5 @@ AudioContext::Constructor(nsISupports* aGlobal, ErrorResult& aRv)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "EnableWebAudioCheck.h"
|
||||
|
||||
class JSContext;
|
||||
class nsIDOMWindow;
|
||||
@ -16,8 +17,11 @@ namespace mozilla {
|
||||
|
||||
class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class AudioContext MOZ_FINAL : public nsISupports,
|
||||
public nsWrapperCache
|
||||
public nsWrapperCache,
|
||||
public EnableWebAudioCheck
|
||||
{
|
||||
explicit AudioContext(nsIDOMWindow* aParentWindow);
|
||||
|
||||
@ -43,4 +47,5 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
32
content/media/webaudio/EnableWebAudioCheck.cpp
Normal file
32
content/media/webaudio/EnableWebAudioCheck.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
#include "EnableWebAudioCheck.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
namespace {
|
||||
|
||||
bool gPrefInitialized = false;
|
||||
bool gWebAudioEnabled = false;
|
||||
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/* static */ bool
|
||||
EnableWebAudioCheck::PrefEnabled()
|
||||
{
|
||||
if (!gPrefInitialized) {
|
||||
Preferences::AddBoolVarCache(&gWebAudioEnabled, "media.webaudio.enabled");
|
||||
gPrefInitialized = true;
|
||||
}
|
||||
return gWebAudioEnabled;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
19
content/media/webaudio/EnableWebAudioCheck.h
Normal file
19
content/media/webaudio/EnableWebAudioCheck.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
// This is a helper class which enables Web Audio to be enabled or disabled
|
||||
// as whole. Individual Web Audio object classes should inherit from this.
|
||||
class EnableWebAudioCheck {
|
||||
public:
|
||||
static bool PrefEnabled();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,8 @@ LIBRARY_NAME := gkconwebaudio_s
|
||||
LIBXUL_LIBRARY := 1
|
||||
|
||||
CPPSRCS := \
|
||||
AudioContext.cpp
|
||||
AudioContext.cpp \
|
||||
EnableWebAudioCheck.cpp \
|
||||
$(NULL)
|
||||
|
||||
PARALLEL_DIRS := test
|
||||
|
@ -11,8 +11,18 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(function() {
|
||||
ok(!window.mozAudioContext, "mozAudioContext should be hidden behind a pref");
|
||||
var accessThrows = false;
|
||||
try {
|
||||
new mozAudioContext();
|
||||
} catch (e) {
|
||||
accessThrows = true;
|
||||
}
|
||||
ok(accessThrows, "mozAudioContext should be hidden behind a pref");
|
||||
SpecialPowers.setBoolPref("media.webaudio.enabled", true);
|
||||
var ac = new mozAudioContext();
|
||||
ok(ac, "Create a mozAudioContext object");
|
||||
SpecialPowers.clearUserPref("media.webaudio.enabled");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
|
@ -211,28 +211,18 @@ SVGFragmentIdentifier::ProcessFragmentIdentifier(nsIDocument *aDocument,
|
||||
const nsSVGViewElement *viewElement = GetViewElement(aDocument, aAnchorName);
|
||||
|
||||
if (viewElement) {
|
||||
if (viewElement->mViewBox.IsExplicitlySet()) {
|
||||
rootElement->mViewBox.SetBaseValue(
|
||||
viewElement->mViewBox.GetBaseValue(), rootElement);
|
||||
} else {
|
||||
RestoreOldViewBox(rootElement);
|
||||
}
|
||||
if (viewElement->mPreserveAspectRatio.IsExplicitlySet()) {
|
||||
rootElement->mPreserveAspectRatio.SetBaseValue(
|
||||
viewElement->mPreserveAspectRatio.GetBaseValue(), rootElement);
|
||||
} else {
|
||||
RestoreOldPreserveAspectRatio(rootElement);
|
||||
}
|
||||
if (viewElement->mEnumAttributes[nsSVGViewElement::ZOOMANDPAN].IsExplicitlySet()) {
|
||||
rootElement->mEnumAttributes[nsSVGSVGElement::ZOOMANDPAN].SetBaseValue(
|
||||
viewElement->mEnumAttributes[nsSVGViewElement::ZOOMANDPAN].GetBaseValue(), rootElement);
|
||||
} else {
|
||||
RestoreOldZoomAndPan(rootElement);
|
||||
if (!rootElement->mCurrentViewID) {
|
||||
rootElement->mCurrentViewID = new nsString();
|
||||
}
|
||||
*rootElement->mCurrentViewID = aAnchorName;
|
||||
rootElement->mUseCurrentView = true;
|
||||
rootElement->InvalidateTransformNotifyFrame();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wasOverridden = !!rootElement->mCurrentViewID;
|
||||
rootElement->mCurrentViewID = nullptr;
|
||||
|
||||
rootElement->mUseCurrentView = ProcessSVGViewSpec(aAnchorName, rootElement);
|
||||
if (rootElement->mUseCurrentView) {
|
||||
return true;
|
||||
@ -243,5 +233,8 @@ SVGFragmentIdentifier::ProcessFragmentIdentifier(nsIDocument *aDocument,
|
||||
rootElement->ClearPreserveAspectRatioProperty();
|
||||
RestoreOldZoomAndPan(rootElement);
|
||||
rootElement->ClearZoomAndPanProperty();
|
||||
if (wasOverridden) {
|
||||
rootElement->InvalidateTransformNotifyFrame();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGSVGElement.h"
|
||||
#include "nsSVGViewElement.h"
|
||||
#include "nsStyleUtil.h"
|
||||
|
||||
#include "nsEventDispatcher.h"
|
||||
@ -159,7 +160,6 @@ NS_INTERFACE_MAP_END_INHERITING(nsSVGSVGElementBase)
|
||||
nsSVGSVGElement::nsSVGSVGElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
FromParser aFromParser)
|
||||
: nsSVGSVGElementBase(aNodeInfo),
|
||||
mCoordCtx(nullptr),
|
||||
mViewportWidth(0),
|
||||
mViewportHeight(0),
|
||||
mCurrentTranslate(0.0f, 0.0f),
|
||||
@ -719,7 +719,14 @@ nsSVGSVGElement::GetTransformToElement(nsIDOMSVGElement *element,
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::GetZoomAndPan(uint16_t *aZoomAndPan)
|
||||
{
|
||||
*aZoomAndPan = mEnumAttributes[ZOOMANDPAN].GetAnimValue();
|
||||
nsSVGViewElement* viewElement = GetCurrentViewElement();
|
||||
if (viewElement && viewElement->mEnumAttributes[
|
||||
nsSVGViewElement::ZOOMANDPAN].IsExplicitlySet()) {
|
||||
*aZoomAndPan = viewElement->mEnumAttributes[
|
||||
nsSVGViewElement::ZOOMANDPAN].GetAnimValue();
|
||||
} else {
|
||||
*aZoomAndPan = mEnumAttributes[ZOOMANDPAN].GetAnimValue();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1069,11 +1076,31 @@ nsSVGSVGElement::HasPreserveAspectRatio()
|
||||
mPreserveAspectRatio.IsAnimated();
|
||||
}
|
||||
|
||||
nsSVGViewElement*
|
||||
nsSVGSVGElement::GetCurrentViewElement() const
|
||||
{
|
||||
if (mCurrentViewID) {
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
Element *element = doc->GetElementById(*mCurrentViewID);
|
||||
if (element && element->Tag() == nsGkAtoms::view) {
|
||||
return static_cast<nsSVGViewElement*>(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsSVGViewBoxRect
|
||||
nsSVGSVGElement::GetViewBoxWithSynthesis(
|
||||
float aViewportWidth, float aViewportHeight) const
|
||||
{
|
||||
if (HasViewBox()) {
|
||||
// The logic here should match HasViewBox().
|
||||
nsSVGViewElement* viewElement = GetCurrentViewElement();
|
||||
if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
|
||||
return viewElement->mViewBox.GetAnimValue();
|
||||
}
|
||||
if (mViewBox.IsExplicitlySet()) {
|
||||
return mViewBox.GetAnimValue();
|
||||
}
|
||||
|
||||
@ -1104,13 +1131,23 @@ nsSVGSVGElement::GetPreserveAspectRatioWithOverride() const
|
||||
}
|
||||
}
|
||||
|
||||
if (!HasViewBox() && ShouldSynthesizeViewBox()) {
|
||||
nsSVGViewElement* viewElement = GetCurrentViewElement();
|
||||
|
||||
// This check is equivalent to "!HasViewBox() && ShouldSynthesizeViewBox()".
|
||||
// We're just holding onto the viewElement that HasViewBox() would look up,
|
||||
// so that we don't have to look it up again later.
|
||||
if (!((viewElement && viewElement->mViewBox.IsExplicitlySet()) ||
|
||||
mViewBox.IsExplicitlySet()) &&
|
||||
ShouldSynthesizeViewBox()) {
|
||||
// If we're synthesizing a viewBox, use preserveAspectRatio="none";
|
||||
return SVGPreserveAspectRatio(
|
||||
nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE,
|
||||
nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE);
|
||||
}
|
||||
|
||||
if (viewElement && viewElement->mPreserveAspectRatio.IsExplicitlySet()) {
|
||||
return viewElement->mPreserveAspectRatio.GetAnimValue();
|
||||
}
|
||||
return mPreserveAspectRatio.GetAnimValue();
|
||||
}
|
||||
|
||||
@ -1122,10 +1159,19 @@ nsSVGSVGElement::GetLength(uint8_t aCtxType)
|
||||
{
|
||||
float h, w;
|
||||
|
||||
if (HasViewBox()) {
|
||||
const nsSVGViewBoxRect& viewbox = mViewBox.GetAnimValue();
|
||||
w = viewbox.width;
|
||||
h = viewbox.height;
|
||||
nsSVGViewElement* viewElement = GetCurrentViewElement();
|
||||
const nsSVGViewBoxRect* viewbox = nullptr;
|
||||
|
||||
// The logic here should match HasViewBox().
|
||||
if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
|
||||
viewbox = &viewElement->mViewBox.GetAnimValue();
|
||||
} else if (mViewBox.IsExplicitlySet()) {
|
||||
viewbox = &mViewBox.GetAnimValue();
|
||||
}
|
||||
|
||||
if (viewbox) {
|
||||
w = viewbox->width;
|
||||
h = viewbox->height;
|
||||
} else if (IsInner()) {
|
||||
nsSVGSVGElement *ctx = GetCtx();
|
||||
w = mLengthAttributes[WIDTH].GetAnimValue(ctx);
|
||||
@ -1230,6 +1276,16 @@ nsSVGSVGElement::GetPreserveAspectRatio()
|
||||
return &mPreserveAspectRatio;
|
||||
}
|
||||
|
||||
bool
|
||||
nsSVGSVGElement::HasViewBox() const
|
||||
{
|
||||
nsSVGViewElement* viewElement = GetCurrentViewElement();
|
||||
if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
|
||||
return true;
|
||||
}
|
||||
return mViewBox.IsExplicitlySet();
|
||||
}
|
||||
|
||||
bool
|
||||
nsSVGSVGElement::ShouldSynthesizeViewBox() const
|
||||
{
|
||||
@ -1303,7 +1359,8 @@ nsSVGSVGElement::
|
||||
"should only override preserveAspectRatio in images");
|
||||
#endif
|
||||
|
||||
if (!HasViewBox() && ShouldSynthesizeViewBox()) {
|
||||
bool hasViewBox = HasViewBox();
|
||||
if (!hasViewBox && ShouldSynthesizeViewBox()) {
|
||||
// My non-<svg:image> clients will have been painting me with a synthesized
|
||||
// viewBox, but my <svg:image> client that's about to paint me now does NOT
|
||||
// want that. Need to tell ourselves to flush our transform.
|
||||
@ -1311,7 +1368,7 @@ nsSVGSVGElement::
|
||||
}
|
||||
mIsPaintingSVGImageElement = true;
|
||||
|
||||
if (!HasViewBox()) {
|
||||
if (!hasViewBox) {
|
||||
return; // preserveAspectRatio irrelevant (only matters if we have viewBox)
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,9 @@ public:
|
||||
|
||||
/**
|
||||
* Returns true if this element has a base/anim value for its "viewBox"
|
||||
* attribute that defines a viewBox rectangle with finite values.
|
||||
* attribute that defines a viewBox rectangle with finite values, or
|
||||
* if there is a view element overriding this element's viewBox and it
|
||||
* has a valid viewBox.
|
||||
*
|
||||
* Note that this does not check whether we need to synthesize a viewBox,
|
||||
* so you must call ShouldSynthesizeViewBox() if you need to check that too.
|
||||
@ -187,9 +189,7 @@ public:
|
||||
* Note also that this method does not pay attention to whether the width or
|
||||
* height values of the viewBox rect are positive!
|
||||
*/
|
||||
bool HasViewBox() const {
|
||||
return mViewBox.IsExplicitlySet();
|
||||
}
|
||||
bool HasViewBox() const;
|
||||
|
||||
/**
|
||||
* Returns true if we should synthesize a viewBox for ourselves (that is, if
|
||||
@ -233,6 +233,12 @@ public:
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
// Returns true IFF our attributes are currently overridden by a <view>
|
||||
// element and that element's ID matches the passed-in string.
|
||||
bool IsOverriddenBy(const nsAString &aViewID) const {
|
||||
return mCurrentViewID && mCurrentViewID->Equals(aViewID);
|
||||
}
|
||||
|
||||
svgFloatSize GetViewportSize() const {
|
||||
return svgFloatSize(mViewportWidth, mViewportHeight);
|
||||
}
|
||||
@ -257,6 +263,8 @@ private:
|
||||
|
||||
// implementation helpers:
|
||||
|
||||
nsSVGViewElement* GetCurrentViewElement() const;
|
||||
|
||||
// Methods for <image> elements to override my "PreserveAspectRatio" value.
|
||||
// These are private so that only our friends (nsSVGImageFrame in
|
||||
// particular) have access.
|
||||
@ -343,7 +351,7 @@ private:
|
||||
nsSVGViewBox mViewBox;
|
||||
SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
|
||||
|
||||
nsSVGSVGElement *mCoordCtx;
|
||||
nsAutoPtr<nsString> mCurrentViewID;
|
||||
|
||||
// The size of the rectangular SVG viewport into which we render. This is
|
||||
// not (necessarily) the same as the content area. See:
|
||||
|
@ -27,6 +27,8 @@ class nsSVGViewElement : public nsSVGViewElementBase,
|
||||
public nsIDOMSVGZoomAndPan
|
||||
{
|
||||
friend class mozilla::SVGFragmentIdentifier;
|
||||
friend class nsSVGSVGElement;
|
||||
friend class nsSVGOuterSVGFrame;
|
||||
friend nsresult NS_NewSVGViewElement(nsIContent **aResult,
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
nsSVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
|
@ -35,7 +35,6 @@ function runTests()
|
||||
var doc = svg.contentWindow.document;
|
||||
|
||||
var tests = [
|
||||
new Test("view", true, "0 200 100 100", "none", null),
|
||||
new Test("unknown", false, null, null, null),
|
||||
new Test("svgView(viewBox(0,0,200,200))", true, "0 0 200 200", null, null),
|
||||
new Test("svgView(preserveAspectRatio(xMaxYMin slice))", true, null, "xMaxYMin slice", null),
|
||||
|
@ -128,7 +128,7 @@ nsXBLDocGlobalObject_setProperty(JSContext *cx, JSHandleObject obj,
|
||||
|
||||
static JSBool
|
||||
nsXBLDocGlobalObject_checkAccess(JSContext *cx, JSHandleObject obj, JSHandleId id,
|
||||
JSAccessMode mode, jsval *vp)
|
||||
JSAccessMode mode, JSMutableHandleValue vp)
|
||||
{
|
||||
uint32_t translated;
|
||||
if (mode & JSACC_WRITE) {
|
||||
@ -218,10 +218,15 @@ XBL_ProtoErrorReporter(JSContext *cx,
|
||||
if (errorObject && consoleService) {
|
||||
uint32_t column = report->uctokenptr - report->uclinebuf;
|
||||
|
||||
const PRUnichar* ucmessage =
|
||||
static_cast<const PRUnichar*>(report->ucmessage);
|
||||
const PRUnichar* uclinebuf =
|
||||
static_cast<const PRUnichar*>(report->uclinebuf);
|
||||
|
||||
errorObject->Init
|
||||
(reinterpret_cast<const PRUnichar*>(report->ucmessage),
|
||||
NS_ConvertUTF8toUTF16(report->filename).get(),
|
||||
reinterpret_cast<const PRUnichar*>(report->uclinebuf),
|
||||
(ucmessage ? nsDependentString(ucmessage) : EmptyString(),
|
||||
NS_ConvertUTF8toUTF16(report->filename),
|
||||
uclinebuf ? nsDependentString(uclinebuf) : EmptyString(),
|
||||
report->lineno, column, report->flags,
|
||||
"xbl javascript"
|
||||
);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user