зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c -> e10s.
This commit is contained in:
Коммит
55caf04feb
|
@ -259,8 +259,7 @@ __try {
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRenderingContext> rc;
|
||||
presShell->CreateRenderingContext(frame, getter_AddRefs(rc));
|
||||
nsCOMPtr<nsIRenderingContext> rc = presShell->GetReferenceRenderingContext();
|
||||
if (!rc) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
button.style.visibility = "hidden";
|
||||
} else {
|
||||
var newLabel = button.getAttribute("label2");
|
||||
button.setAttribute("label", newLabel);
|
||||
button.textContent = newLabel;
|
||||
buttonClicked = true;
|
||||
}
|
||||
}
|
||||
|
@ -139,11 +139,9 @@
|
|||
</div>
|
||||
|
||||
<!-- Button -->
|
||||
<xul:button xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="errorTryAgain"
|
||||
label="&retry.label;"
|
||||
label2="&robots.dontpress;"
|
||||
oncommand="robotButton();" />
|
||||
<button id="errorTryAgain"
|
||||
label2="&robots.dontpress;"
|
||||
onclick="robotButton();">&retry.label;</button>
|
||||
|
||||
<img src="chrome://browser/content/aboutRobots-widget-left.png"
|
||||
style="position: absolute; bottom: -12px; left: -10px;"/>
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
</html:head>
|
||||
|
||||
<popupset id="contextmenus">
|
||||
<popup id="tabListContext">
|
||||
<menupopup id="tabListContext">
|
||||
<menuitem label="&tabs.context.openTab.label;"
|
||||
accesskey="&tabs.context.openTab.accesskey;"
|
||||
oncommand="RemoteTabViewer.openSelected()"
|
||||
|
@ -82,7 +82,7 @@
|
|||
accesskey="&tabs.context.refreshList.accesskey;"
|
||||
oncommand="RemoteTabViewer.buildList()"
|
||||
showFor="all"/>
|
||||
</popup>
|
||||
</menupopup>
|
||||
</popupset>
|
||||
<richlistbox context="tabListContext" id="tabsList" seltype="multiple"
|
||||
align="center" flex="1"
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
%brandDTD;
|
||||
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
|
||||
%browserDTD;
|
||||
<!ENTITY % baseMenuDTD SYSTEM "chrome://browser/locale/baseMenuOverlay.dtd" >
|
||||
%baseMenuDTD;
|
||||
<!ENTITY % globalRegionDTD SYSTEM "chrome://global-region/locale/region.dtd">
|
||||
%globalRegionDTD;
|
||||
<!ENTITY % charsetDTD SYSTEM "chrome://global/locale/charsetOverlay.dtd" >
|
||||
|
|
|
@ -653,7 +653,6 @@ HistoryMenu.prototype = {
|
|||
m = undoPopup.appendChild(document.createElement("menuitem"));
|
||||
m.id = "menu_restoreAllTabs";
|
||||
m.setAttribute("label", strings.getString("menuRestoreAllTabs.label"));
|
||||
m.setAttribute("accesskey", strings.getString("menuRestoreAllTabs.accesskey"));
|
||||
m.addEventListener("command", function() {
|
||||
for (var i = 0; i < undoItems.length; i++)
|
||||
undoCloseTab();
|
||||
|
@ -731,7 +730,6 @@ HistoryMenu.prototype = {
|
|||
let m = undoPopup.appendChild(document.createElement("menuitem"));
|
||||
m.id = "menu_restoreAllWindows";
|
||||
m.setAttribute("label", gNavigatorBundle.getString("menuRestoreAllWindows.label"));
|
||||
m.setAttribute("accesskey", gNavigatorBundle.getString("menuRestoreAllWindows.accesskey"));
|
||||
m.setAttribute("oncommand",
|
||||
"for (var i = 0; i < " + undoItems.length + "; i++) undoCloseWindow();");
|
||||
},
|
||||
|
|
|
@ -139,32 +139,32 @@ let TabView = {
|
|||
|
||||
// ----------
|
||||
updateContextMenu: function(tab, popup) {
|
||||
let separator = document.getElementById("context_tabViewNamedGroups");
|
||||
let isEmpty = true;
|
||||
|
||||
while(popup.lastChild && popup.lastChild.id != "context_namedGroups")
|
||||
popup.removeChild(popup.lastChild);
|
||||
while (popup.firstChild && popup.firstChild != separator)
|
||||
popup.removeChild(popup.firstChild);
|
||||
|
||||
let self = this;
|
||||
this._initFrame(function() {
|
||||
let activeGroup = tab.tabItem.parent;
|
||||
let groupItems = self._window.GroupItems.groupItems;
|
||||
|
||||
|
||||
groupItems.forEach(function(groupItem) {
|
||||
if (groupItem.getTitle().length > 0 &&
|
||||
(!activeGroup || activeGroup.id != groupItem.id)) {
|
||||
let menuItem = self._createGroupMenuItem(groupItem);
|
||||
popup.appendChild(menuItem);
|
||||
popup.insertBefore(menuItem, separator);
|
||||
isEmpty = false;
|
||||
}
|
||||
});
|
||||
document.getElementById("context_namedGroups").hidden = isEmpty;
|
||||
separator.hidden = isEmpty;
|
||||
});
|
||||
},
|
||||
|
||||
// ----------
|
||||
_createGroupMenuItem : function(groupItem) {
|
||||
let menuItem = document.createElement("menuitem")
|
||||
menuItem.setAttribute("class", "group");
|
||||
menuItem.setAttribute("label", groupItem.getTitle());
|
||||
menuItem.setAttribute(
|
||||
"oncommand",
|
||||
|
|
|
@ -1450,12 +1450,6 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
|||
// bookmark-all-tabs command
|
||||
gBookmarkAllTabsHandler.init();
|
||||
|
||||
// Attach a listener to watch for "command" events bubbling up from error
|
||||
// pages. This lets us fix bugs like 401575 which require error page UI to
|
||||
// do privileged things, without letting error pages have any privilege
|
||||
// themselves.
|
||||
gBrowser.addEventListener("command", BrowserOnCommand, false);
|
||||
|
||||
ctrlTab.readPref();
|
||||
gPrefService.addObserver(ctrlTab.prefName, ctrlTab, false);
|
||||
gPrefService.addObserver(allTabs.prefName, allTabs, false);
|
||||
|
@ -2491,9 +2485,9 @@ function BrowserImport()
|
|||
/**
|
||||
* Handle command events bubbling up from error page content
|
||||
*/
|
||||
function BrowserOnCommand(event) {
|
||||
function BrowserOnClick(event) {
|
||||
// Don't trust synthetic events
|
||||
if (!event.isTrusted)
|
||||
if (!event.isTrusted || event.target.localName != "button")
|
||||
return;
|
||||
|
||||
var ot = event.originalTarget;
|
||||
|
@ -3588,6 +3582,9 @@ function updateEditUIVisibility()
|
|||
let editMenuPopupState = document.getElementById("menu_EditPopup").state;
|
||||
let contextMenuPopupState = document.getElementById("contentAreaContextMenu").state;
|
||||
let placesContextMenuPopupState = document.getElementById("placesContext").state;
|
||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||
let appMenuPopupState = document.getElementById("appmenu-popup").state;
|
||||
#endif
|
||||
|
||||
// The UI is visible if the Edit menu is opening or open, if the context menu
|
||||
// is open, or if the toolbar has been customized to include the Cut, Copy,
|
||||
|
@ -3598,6 +3595,10 @@ function updateEditUIVisibility()
|
|||
contextMenuPopupState == "open" ||
|
||||
placesContextMenuPopupState == "showing" ||
|
||||
placesContextMenuPopupState == "open" ||
|
||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||
appMenuPopupState == "showing" ||
|
||||
appMenuPopupState == "open" ||
|
||||
#endif
|
||||
document.getElementById("cut-button") ||
|
||||
document.getElementById("copy-button") ||
|
||||
document.getElementById("paste-button") ? true : false;
|
||||
|
@ -4080,6 +4081,7 @@ var XULBrowserWindow = {
|
|||
onStateChange: function (aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
const nsIWebProgressListener = Ci.nsIWebProgressListener;
|
||||
const nsIChannel = Ci.nsIChannel;
|
||||
|
||||
if (aStateFlags & nsIWebProgressListener.STATE_START &&
|
||||
aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
|
||||
|
||||
|
@ -4526,17 +4528,33 @@ var CombinedStopReload = {
|
|||
};
|
||||
|
||||
var TabsProgressListener = {
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
if (aRequest instanceof Ci.nsIChannel &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_START &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT &&
|
||||
gCrashReporter.enabled) {
|
||||
gCrashReporter.annotateCrashReport("URL", aRequest.URI.spec);
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
// Attach a listener to watch for "click" events bubbling up from error
|
||||
// pages and other similar page. This lets us fix bugs like 401575 which
|
||||
// require error page UI to do privileged things, without letting error
|
||||
// pages have any privilege themselves.
|
||||
// We can't look for this during onLocationChange since at that point the
|
||||
// document URI is not yet the about:-uri of the error page.
|
||||
|
||||
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
||||
/^about:/.test(aBrowser.contentWindow.document.documentURI)) {
|
||||
aBrowser.addEventListener("click", BrowserOnClick, false);
|
||||
aBrowser.addEventListener("pagehide", function () {
|
||||
aBrowser.removeEventListener("click", BrowserOnClick, false);
|
||||
aBrowser.removeEventListener("pagehide", arguments.callee, true);
|
||||
}, true);
|
||||
}
|
||||
},
|
||||
|
||||
onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI) {
|
||||
// Filter out any sub-frame loads
|
||||
if (aBrowser.contentWindow == aWebProgress.DOMWindow)
|
||||
|
@ -4675,7 +4693,7 @@ nsBrowserAccess.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
function onViewToolbarsPopupShowing(aEvent) {
|
||||
function onViewToolbarsPopupShowing(aEvent, aInsertPoint) {
|
||||
var popup = aEvent.target;
|
||||
if (popup != aEvent.currentTarget)
|
||||
return;
|
||||
|
@ -4689,7 +4707,7 @@ function onViewToolbarsPopupShowing(aEvent) {
|
|||
popup.removeChild(deadItem);
|
||||
}
|
||||
|
||||
var firstMenuItem = popup.firstChild;
|
||||
var firstMenuItem = aInsertPoint || popup.firstChild;
|
||||
|
||||
for (i = 0; i < gNavToolbox.childNodes.length; ++i) {
|
||||
var toolbar = gNavToolbox.childNodes[i];
|
||||
|
@ -5844,15 +5862,12 @@ function warnAboutClosingWindow() {
|
|||
return gBrowser.warnAboutClosingTabs(true);
|
||||
|
||||
// Figure out if there's at least one other browser window around.
|
||||
let foundOtherBrowserWindow = false;
|
||||
let e = Services.wm.getEnumerator("navigator:browser");
|
||||
while (e.hasMoreElements() && !foundOtherBrowserWindow) {
|
||||
while (e.hasMoreElements()) {
|
||||
let win = e.getNext();
|
||||
if (win != window && win.toolbar.visible)
|
||||
foundOtherBrowserWindow = true;
|
||||
return gBrowser.warnAboutClosingTabs(true);
|
||||
}
|
||||
if (foundOtherBrowserWindow)
|
||||
return gBrowser.warnAboutClosingTabs(true);
|
||||
|
||||
let os = Services.obs;
|
||||
|
||||
|
@ -7454,6 +7469,10 @@ let gPrivateBrowsingUI = {
|
|||
// Disable the menu item in auto-start mode
|
||||
document.getElementById("privateBrowsingItem")
|
||||
.setAttribute("disabled", "true");
|
||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||
document.getElementById("appmenu_privateBrowsing")
|
||||
.setAttribute("disabled", "true");
|
||||
#endif
|
||||
document.getElementById("Tools:PrivateBrowsing")
|
||||
.setAttribute("disabled", "true");
|
||||
}
|
||||
|
@ -7521,6 +7540,10 @@ let gPrivateBrowsingUI = {
|
|||
// Enable the menu item in after exiting the auto-start mode
|
||||
document.getElementById("privateBrowsingItem")
|
||||
.removeAttribute("disabled");
|
||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||
document.getElementById("appmenu_privateBrowsing")
|
||||
.removeAttribute("disabled");
|
||||
#endif
|
||||
document.getElementById("Tools:PrivateBrowsing")
|
||||
.removeAttribute("disabled");
|
||||
|
||||
|
@ -7539,6 +7562,11 @@ let gPrivateBrowsingUI = {
|
|||
let pbMenuItem = document.getElementById("privateBrowsingItem");
|
||||
pbMenuItem.setAttribute("label", pbMenuItem.getAttribute(aMode + "label"));
|
||||
pbMenuItem.setAttribute("accesskey", pbMenuItem.getAttribute(aMode + "accesskey"));
|
||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||
let appmenupbMenuItem = document.getElementById("appmenu_privateBrowsing");
|
||||
appmenupbMenuItem.setAttribute("label", appmenupbMenuItem.getAttribute(aMode + "label"));
|
||||
appmenupbMenuItem.setAttribute("accesskey", appmenupbMenuItem.getAttribute(aMode + "accesskey"));
|
||||
#endif
|
||||
},
|
||||
|
||||
toggleMode: function PBUI_toggleMode() {
|
||||
|
|
|
@ -128,13 +128,11 @@
|
|||
oncommand="gBrowser.unpinTab(TabContextMenu.contextTab);"/>
|
||||
<menu id="context_tabViewMenu" label="&moveToGroup.label;"
|
||||
accesskey="&moveToGroup.accesskey;">
|
||||
<menupopup id="context_tabViewMenuPopup"
|
||||
<menupopup id="context_tabViewMenuPopup"
|
||||
onpopupshowing="if (event.target == this) TabView.updateContextMenu(TabContextMenu.contextTab, this);">
|
||||
<menuitem label="&moveToNewGroup.label;"
|
||||
accesskey="&moveToNewGroup.accesskey;"
|
||||
<menuseparator id="context_tabViewNamedGroups" hidden="true"/>
|
||||
<menuitem label="&moveToNewGroup.label;"
|
||||
oncommand="TabView.moveTabTo(TabContextMenu.contextTab, null);"/>
|
||||
<menuitem id="context_namedGroups" label="&namedGroups.label;"
|
||||
disabled="true"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuseparator/>
|
||||
|
@ -451,148 +449,300 @@
|
|||
</popupset>
|
||||
|
||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||
<hbox id="appmenu-button-container">
|
||||
<button id="appmenu-button"
|
||||
type="menu"
|
||||
label="&brandShortName;"
|
||||
style="-moz-user-focus: ignore;">
|
||||
<menupopup id="appmenu-popup">
|
||||
<hbox flex="1" class="split-menuitem">
|
||||
<menuitem id="appmenu_newTab"
|
||||
class="split-menuitem-item"
|
||||
flex="1"
|
||||
label="&tabCmd.label;"
|
||||
command="cmd_newNavigatorTab"/>
|
||||
<menu class="split-menuitem-menu">
|
||||
<menupopup>
|
||||
<menuitem id="appmenu_newTab_sub"
|
||||
label="&tabCmd.label;"
|
||||
command="cmd_newNavigatorTab"/>
|
||||
<menuitem id="appmenu_newNavigator"
|
||||
label="&newNavigatorCmd.label;"
|
||||
command="cmd_newNavigator"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</hbox>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenu_savePage"
|
||||
label="&savePageCmd.label;"
|
||||
command="Browser:SavePage"/>
|
||||
<menuitem id="appmenu_sendLink"
|
||||
label="&sendPageCmd.label;"
|
||||
command="Browser:SendLink"/>
|
||||
<hbox flex="1" class="split-menuitem">
|
||||
<menuitem id="appmenu_print"
|
||||
class="split-menuitem-item"
|
||||
flex="1"
|
||||
label="&appMenuPrintCmd.label;"
|
||||
command="cmd_print"/>
|
||||
<menu class="split-menuitem-menu">
|
||||
<menupopup>
|
||||
<menuitem id="menu_printSetup"
|
||||
label="&printSetupCmd.label;"
|
||||
command="cmd_pageSetup"/>
|
||||
<menuitem id="menu_printPreview"
|
||||
label="&printPreviewCmd.label;"
|
||||
command="cmd_printPreview"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</hbox>
|
||||
<menuitem id="appmenu_find"
|
||||
label="&findOnCmd.label;"
|
||||
command="cmd_find"/>
|
||||
<menuseparator/>
|
||||
<menu id="appmenu_history"
|
||||
label="&historyMenu.label;">
|
||||
<menupopup id="appmenu_history_popup"
|
||||
placespopup="true"
|
||||
oncommand="this.parentNode._placesView._onCommand(event);"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
onpopupshowing="if (!this.parentNode._placesView)
|
||||
new HistoryMenu(event);"
|
||||
tooltip="bhTooltip"
|
||||
popupsinherittooltip="true">
|
||||
<menuitem id="appmenu_sanitizeHistory"
|
||||
label="&clearRecentHistory.label;"
|
||||
key="key_sanitize"
|
||||
command="Tools:Sanitize"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenu_showAllHistory"
|
||||
label="&showAllHistoryCmd2.label;"
|
||||
key="showAllHistoryKb"
|
||||
command="Browser:ShowAllHistory"/>
|
||||
<menuseparator class="hide-if-empty-places-result"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuseparator/>
|
||||
<menu id="appmenu_developer"
|
||||
label="&developerMenu.label;">
|
||||
<menupopup id="appmenu_developer_popup">
|
||||
<menuitem id="appmenu_pageSource"
|
||||
label="&pageSourceCmd.label;"
|
||||
command="View:PageSource"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenu_pageInspect"
|
||||
type="checkbox"
|
||||
label="&inspectMenu.label;"
|
||||
command="Tools:Inspect"/>
|
||||
<menuitem id="appmenu_webConsole"
|
||||
label="&webConsoleCmd.label;"
|
||||
oncommand="HUDConsoleUI.toggleHUD();"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuseparator/>
|
||||
<menu id="appmenu_customize"
|
||||
label="&appMenuCustomize.label;">
|
||||
<menupopup id="appmenu_customizeMenu"
|
||||
onpopupshowing="onViewToolbarsPopupShowing(event);">
|
||||
<menuseparator/>
|
||||
<menuitem command="cmd_ToggleTabsOnTop"
|
||||
type="checkbox"
|
||||
label="&viewTabsOnTop.label;"/>
|
||||
<menuitem id="appmenu_toolbarLayout"
|
||||
label="&appMenuToolbarLayout.label;"
|
||||
command="cmd_CustomizeToolbars"/>
|
||||
<menu id="appmenu_sidebars"
|
||||
label="&appMenuSidebars.label;">
|
||||
<menupopup id="appmenu_sidebarMenu">
|
||||
<menuitem id="appmenu_bookmarksSidebar"
|
||||
key="viewBookmarksSidebarKb"
|
||||
observes="viewBookmarksSidebar"/>
|
||||
<menuitem id="appmenu_historySidebar"
|
||||
key="key_gotoHistory"
|
||||
observes="viewHistorySidebar"
|
||||
label="&historyButton.label;"/>
|
||||
<hbox id="appmenu-button-container">
|
||||
<button id="appmenu-button"
|
||||
type="menu"
|
||||
label="&brandShortName;"
|
||||
style="-moz-user-focus: ignore;">
|
||||
<menupopup id="appmenu-popup"
|
||||
onpopupshowing="updateEditUIVisibility();">
|
||||
<hbox>
|
||||
<vbox id="appmenuPrimaryPane">
|
||||
<hbox flex="1"
|
||||
class="split-menuitem">
|
||||
<menuitem id="appmenu_newTab"
|
||||
class="split-menuitem-item"
|
||||
flex="1"
|
||||
label="&tabCmd.label;"
|
||||
command="cmd_newNavigatorTab"/>
|
||||
<menu class="split-menuitem-menu">
|
||||
<menupopup>
|
||||
<menuitem id="appmenu_newTab_popup"
|
||||
label="&tabCmd.label;"
|
||||
command="cmd_newNavigatorTab"/>
|
||||
<menuitem id="appmenu_newNavigator"
|
||||
label="&newNavigatorCmd.label;"
|
||||
command="cmd_newNavigator"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenu_openFile"
|
||||
label="&openFileCmd.label;"
|
||||
command="Browser:OpenFile"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</hbox>
|
||||
<menuitem id="appmenu_privateBrowsing"
|
||||
class="menuitem-iconic"
|
||||
label="&privateBrowsingCmd.start.label;"
|
||||
accesskey="&privateBrowsingCmd.start.accesskey;"
|
||||
startlabel="&privateBrowsingCmd.start.label;"
|
||||
stoplabel="&privateBrowsingCmd.stop.label;"
|
||||
command="Tools:PrivateBrowsing"/>
|
||||
<menuseparator class="menu-seperator"/>
|
||||
<hbox class="split-menuitem">
|
||||
<menuitem id="appmenu-edit-menuitem"
|
||||
label="&editMenu.label;"
|
||||
disabled="true"/>
|
||||
<toolbarbutton id="appmenu-cut"
|
||||
class="appmenu-edit-button"
|
||||
command="cmd_cut"
|
||||
onclick="if (!this.disabled) hidePopup();"
|
||||
tooltiptext="&cutButton.tooltip;"/>
|
||||
<toolbarbutton id="appmenu-copy"
|
||||
class="appmenu-edit-button"
|
||||
command="cmd_copy"
|
||||
onclick="if (!this.disabled) hidePopup();"
|
||||
tooltiptext="©Button.tooltip;"/>
|
||||
<toolbarbutton id="appmenu-paste"
|
||||
class="appmenu-edit-button"
|
||||
command="cmd_paste"
|
||||
onclick="if (!this.disabled) hidePopup();"
|
||||
tooltiptext="&pasteButton.tooltip;"/>
|
||||
</hbox>
|
||||
<menuitem id="appmenu_find"
|
||||
label="&appMenuFind.label;"
|
||||
command="cmd_find"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenu_savePage"
|
||||
label="&savePageCmd.label;"
|
||||
command="Browser:SavePage"/>
|
||||
<menuitem id="appmenu_sendLink"
|
||||
label="&sendPageCmd.label;"
|
||||
command="Browser:SendLink"/>
|
||||
<hbox flex="1"
|
||||
class="split-menuitem">
|
||||
<menuitem id="appmenu_print"
|
||||
class="menuitem-iconic"
|
||||
flex="1"
|
||||
label="&printCmd.label;"
|
||||
command="cmd_print"/>
|
||||
<menu class="split-menuitem-menu">
|
||||
<menupopup>
|
||||
<menuitem id="appmenu_print_popup"
|
||||
class="menuitem-iconic"
|
||||
label="&printCmd.label;"
|
||||
command="cmd_print"/>
|
||||
<menuitem id="appmenu_printPreview"
|
||||
label="&printPreviewCmd.label;"
|
||||
command="cmd_printPreview"/>
|
||||
<menuitem id="appmenu_printSetup"
|
||||
label="&printSetupCmd.label;"
|
||||
command="cmd_pageSetup"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenu_openAddons"
|
||||
</hbox>
|
||||
<menuseparator/>
|
||||
<menu id="appmenu_developer"
|
||||
label="&developerMenu.label;">
|
||||
<menupopup id="appmenu_developer_popup">
|
||||
<menuitem id="appmenu_webConsole"
|
||||
label="&webConsoleCmd.label;"
|
||||
type="checkbox"
|
||||
oncommand="HUDConsoleUI.toggleHUD();"/>
|
||||
<menuitem id="appmenu_pageInspect"
|
||||
label="&inspectMenu.label;"
|
||||
type="checkbox"
|
||||
command="Tools:Inspect"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenu_pageSource"
|
||||
label="&viewPageSourceCmd.label;"
|
||||
command="View:PageSource"/>
|
||||
<menuseparator/>
|
||||
<menuitem label="&goOfflineCmd.label;"
|
||||
accesskey="&goOfflineCmd.accesskey;"
|
||||
type="checkbox"
|
||||
oncommand="BrowserOffline.toggleOfflineStatus();"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenu_fullScreen"
|
||||
label="&fullScreenCmd.label;"
|
||||
type="checkbox"
|
||||
observes="View:FullScreen"/>
|
||||
<menuitem id="appmenu-quit"
|
||||
class="menuitem-iconic"
|
||||
#ifdef XP_WIN
|
||||
label="&quitApplicationCmdWin.label;"
|
||||
#else
|
||||
label="&quitApplicationCmd.label;"
|
||||
#endif
|
||||
command="cmd_quitApplication"/>
|
||||
</vbox>
|
||||
<vbox id="appmenuSecondaryPane">
|
||||
<hbox class="split-menuitem">
|
||||
<menuitem id="appmenu_BookmarkItem"
|
||||
class="menuitem-iconic"
|
||||
flex="1"
|
||||
label="&bookmarksMenu.label;"
|
||||
command="Browser:ShowAllBookmarks"/>
|
||||
<menu id="appmenuBookmarkMenu"
|
||||
class="split-menuitem-menu">
|
||||
<menupopup id="appmenuBookmarkMenu_popup"
|
||||
placespopup="true"
|
||||
context="placesContext"
|
||||
openInTabs="children"
|
||||
oncommand="BookmarksEventHandler.onCommand(event);"
|
||||
onclick="BookmarksEventHandler.onClick(event);"
|
||||
onpopupshowing="BookmarksMenuButton.onPopupShowing(event);
|
||||
if (!this.parentNode._placesView)new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');
|
||||
this.appendChild(document.getElementById('appmenuBookmarkMenu_unsorted_seperator'));
|
||||
this.appendChild(document.getElementById('appmenuBookmarkMenu_unsorted-menuitem'));"
|
||||
tooltip="bhTooltip"
|
||||
popupsinherittooltip="true">
|
||||
<menuseparator id="appmenuBookmarkMenu_unsorted_seperator"/>
|
||||
<menuitem id="appmenuBookmarkMenu_unsorted-menuitem"
|
||||
label="&appMenuUnsorted.label;"
|
||||
oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"
|
||||
class="menuitem-iconic"/>
|
||||
<menuitem id="appmenuBookmarkMenu_organize_bookmarks"
|
||||
label="&organizeBookmarks.label;"
|
||||
key="manBookmarkKb"
|
||||
command="Browser:ShowAllBookmarks"
|
||||
context=""/>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenuBookmarkThisPage"
|
||||
class="menuitem-iconic"
|
||||
label="&bookmarkThisPageCmd.label;"
|
||||
command="Browser:AddBookmarkAs"
|
||||
key="addBookmarkAsKb"/>
|
||||
<menuitem id="subscribeToPageMenuitem"
|
||||
class="menuitem-iconic"
|
||||
label="&subscribeToPageMenuitem.label;"
|
||||
oncommand="return FeedHandler.subscribeToFeed(null, event);"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
disabled="true"/>
|
||||
<menu id="subscribeToPageMenupopup"
|
||||
class="menu-iconic"
|
||||
label="&subscribeToPageMenupopup.label;"
|
||||
hidden="true">
|
||||
<menupopup id="subscribeToPageSubmenuMenupopup"
|
||||
onpopupshowing="return FeedHandler.buildFeedList(event.target);"
|
||||
oncommand="return FeedHandler.subscribeToFeed(null, event);"
|
||||
onclick="checkForMiddleClick(this, event);"/>
|
||||
</menu>
|
||||
<menuseparator/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</hbox>
|
||||
<hbox class="split-menuitem">
|
||||
<menuitem id="appmenu_HistoryItem"
|
||||
class="menuitem-iconic"
|
||||
flex="1"
|
||||
label="&historyMenu.label;"
|
||||
command="Browser:ShowAllHistory"/>
|
||||
<menu id="appmenu_history"
|
||||
class="split-menuitem-menu">
|
||||
<menupopup id="appmenu_history_popup"
|
||||
placespopup="true"
|
||||
oncommand="this.parentNode._placesView._onCommand(event);"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
onpopupshowing="if (!this.parentNode._placesView) new HistoryMenu(event);"
|
||||
tooltip="bhTooltip"
|
||||
popupsinherittooltip="true">
|
||||
<menuitem id="appmenu_showAllHistory"
|
||||
label="&showAllHistoryCmd2.label;"
|
||||
key="showAllHistoryKb"
|
||||
command="Browser:ShowAllHistory"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenu_sanitizeHistory"
|
||||
label="&clearRecentHistory.label;"
|
||||
key="key_sanitize"
|
||||
command="Tools:Sanitize"/>
|
||||
<menuseparator class="hide-if-empty-places-result"/>
|
||||
<menu id="historyUndoMenu"
|
||||
label="&historyUndoMenu.label;"
|
||||
disabled="true">
|
||||
<menupopup id="historyUndoPopup"
|
||||
onpopupshowing="_placesView.populateUndoSubmenu();"/>
|
||||
</menu>
|
||||
<menu id="historyUndoWindowMenu"
|
||||
label="&historyUndoWindowMenu.label;"
|
||||
disabled="true">
|
||||
<menupopup id="historyUndoPopup"
|
||||
onpopupshowing="_placesView.populateUndoWindowSubmenu();"/>
|
||||
</menu>
|
||||
<menuseparator/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</hbox>
|
||||
<menuitem id="appmenu_downloads"
|
||||
label="&downloads.label;"
|
||||
command="Tools:Downloads"/>
|
||||
<spacer id="appmenuSecondaryPane-spacer"/>
|
||||
<menuitem id="appmenu_addons"
|
||||
class="menuitem-iconic"
|
||||
label="&addons.label;"
|
||||
command="Tools:Addons"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuitem id="appmenu_preferences"
|
||||
<hbox class="split-menuitem">
|
||||
<menuitem id="appmenu_customize"
|
||||
label="&preferencesCmd.label;"
|
||||
class="split-menuitem-item"
|
||||
flex="1"
|
||||
oncommand="openPreferences();"/>
|
||||
<menu class="split-menuitem-menu"
|
||||
label="&preferencesCmd.label;">
|
||||
<menupopup id="appmenu_customizeMenu"
|
||||
onpopupshowing="onViewToolbarsPopupShowing(event, (document.getElementById('appmenuToggleStatusbar')));">
|
||||
<menuitem id="appmenu_preferences"
|
||||
#ifdef XP_UNIX
|
||||
label="&preferencesCmdUnix.label;"
|
||||
label="&preferencesCmdUnix.label;"
|
||||
#else
|
||||
label="&preferencesCmd.label;"
|
||||
label="&preferencesCmd.label;"
|
||||
#endif
|
||||
oncommand="openPreferences();"/>
|
||||
<menuitem id="appmenu_openHelp"
|
||||
label="&appMenuHelp.label;"
|
||||
oncommand="openHelpLink('firefox-help')"
|
||||
onclick="checkForMiddleClick(this, event);"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenu_quit"
|
||||
#ifdef XP_WIN
|
||||
label="&quitApplicationCmdWin.label;"
|
||||
#else
|
||||
label="&quitApplicationCmd.label;"
|
||||
#endif
|
||||
command="cmd_quitApplication"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
</hbox>
|
||||
oncommand="openPreferences();"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenuToggleStatusbar"
|
||||
type="checkbox"
|
||||
command="cmd_toggleTaskbar"
|
||||
observes="toggle_taskbar"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenuToggleTabs"
|
||||
label="&viewTabsOnTop.label;"
|
||||
type="checkbox"
|
||||
command="cmd_ToggleTabsOnTop"/>
|
||||
<menuitem id="appmenu_toolbarLayout"
|
||||
label="&appMenuToolbarLayout.label;"
|
||||
command="cmd_CustomizeToolbars"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</hbox>
|
||||
<hbox class="split-menuitem">
|
||||
<menuitem id="appmenu_helpItem"
|
||||
flex="1"
|
||||
label="&helpMenu.label;"
|
||||
oncommand="openHelpLink('firefox-help')"/>
|
||||
<menu id="appmenu_about_menu"
|
||||
class="split-menuitem-menu">
|
||||
<menupopup>
|
||||
<menuitem id="appmenu_openHelp"
|
||||
label="&helpMenu.label;"
|
||||
oncommand="openHelpLink('firefox-help')"
|
||||
onclick="checkForMiddleClick(this, event);"/>
|
||||
<menuitem id="appmenu_help_getting_started"
|
||||
label="&appMenuGettingStarted.label;"
|
||||
oncommand="gBrowser.selectedTab = gBrowser.addTab('http://www.mozilla.com/firefox/central/');"
|
||||
onclick="checkForMiddleClick(this, event);"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="appmenu_help_about"
|
||||
label="&aboutProduct.label;"
|
||||
oncommand="openAboutDialog();"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</menupopup>
|
||||
</button>
|
||||
</hbox>
|
||||
#endif
|
||||
|
||||
<deck flex="1" id="tab-view-deck">
|
||||
|
|
|
@ -1202,8 +1202,6 @@
|
|||
b._fastFind = this.fastFind;
|
||||
b.droppedLinkHandler = handleDroppedLink;
|
||||
|
||||
this.tabContainer.adjustTabstrip();
|
||||
|
||||
// Dispatch a new tab notification. We do this once we're
|
||||
// entirely done, so that things are in a consistent state
|
||||
// even if the event listener opens or closes tabs.
|
||||
|
@ -1258,10 +1256,8 @@
|
|||
<parameter name="aAll"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var tabsToClose = this.tabs.length;
|
||||
|
||||
if (!aAll)
|
||||
tabsToClose = this.visibleTabs.length - (1 + this._numPinnedTabs);
|
||||
var tabsToClose = (aAll ? this.tabs.length : this.visibleTabs.length - 1)
|
||||
- gBrowser._numPinnedTabs;
|
||||
if (tabsToClose <= 1)
|
||||
return true;
|
||||
|
||||
|
@ -2744,11 +2740,13 @@
|
|||
return;
|
||||
|
||||
if (this.mTabstrip.smoothScroll) {
|
||||
let selected = this.selectedItem.getBoundingClientRect();
|
||||
let selected = !this.selectedItem.pinned &&
|
||||
this.selectedItem.getBoundingClientRect();
|
||||
|
||||
// Can we make both the new tab and the selected tab completely visible?
|
||||
if (Math.max(tab.right - selected.left, selected.right - tab.left) <=
|
||||
scrollRect.width) {
|
||||
if (!selected ||
|
||||
Math.max(tab.right - selected.left, selected.right - tab.left) <=
|
||||
scrollRect.width) {
|
||||
this.mTabstrip.ensureElementIsVisible(aTab);
|
||||
return;
|
||||
}
|
||||
|
@ -2849,6 +2847,8 @@
|
|||
if (tab.parentNode != this)
|
||||
return;
|
||||
|
||||
this.adjustTabstrip();
|
||||
|
||||
if (tab.getAttribute("selected") == "true") {
|
||||
this._fillTrailingGap();
|
||||
this._handleTabSelect();
|
||||
|
|
|
@ -13,7 +13,7 @@ function test() {
|
|||
waitForExplicitFinish();
|
||||
|
||||
Services.prefs.setBoolPref("browser.tabs.animate", true);
|
||||
nextAsyncText();
|
||||
preperForNextText();
|
||||
}
|
||||
|
||||
function tabAdded() {
|
||||
|
@ -46,10 +46,15 @@ var asyncTests = [
|
|||
}
|
||||
];
|
||||
|
||||
function nextAsyncText() {
|
||||
function preperForNextText() {
|
||||
info("tests left: " + asyncTests.length + "; starting next");
|
||||
var tab = gBrowser.addTab("about:blank", { skipAnimation: true });
|
||||
executeSoon(function () {
|
||||
nextAsyncText(tab);
|
||||
});
|
||||
}
|
||||
|
||||
function nextAsyncText(tab) {
|
||||
var gotCloseEvent = false;
|
||||
|
||||
tab.addEventListener("TabClose", function () {
|
||||
|
@ -68,7 +73,7 @@ function nextAsyncText() {
|
|||
is(tab.parentNode, null, "tab removed after at most " + MAX_WAIT_TIME + " ms");
|
||||
|
||||
if (asyncTests.length)
|
||||
nextAsyncText();
|
||||
preperForNextText();
|
||||
else
|
||||
cleanup();
|
||||
}, DEFAULT_ANIMATION_LENGTH);
|
||||
|
|
|
@ -246,7 +246,7 @@
|
|||
<h2>&certerror.whatShouldIDo.heading;</h2>
|
||||
<div id="whatShouldIDoContentText">
|
||||
<p>&certerror.whatShouldIDo.content;</p>
|
||||
<xul:button xmlns:xul='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' id='getMeOutOfHereButton' label='&certerror.getMeOutOfHere.label;'/>
|
||||
<button id='getMeOutOfHereButton'>&certerror.getMeOutOfHere.label;</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -262,7 +262,7 @@
|
|||
<div>
|
||||
<p>&certerror.expert.content;</p>
|
||||
<p>&certerror.expert.contentPara2;</p>
|
||||
<xul:button xmlns:xul='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' id='exceptionDialogButton' label='&certerror.addException.label;'/>
|
||||
<button id='exceptionDialogButton'>&certerror.addException.label;</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#feedSubscribeLine {
|
||||
-moz-binding: url(subscribe.xml#feedreaderUI);
|
||||
}
|
|
@ -16,14 +16,17 @@
|
|||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<html id="feedHandler"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>&feedPage.title;</title>
|
||||
<link rel="stylesheet"
|
||||
href="chrome://browser/skin/feeds/subscribe.css"
|
||||
type="text/css"
|
||||
media="all"/>
|
||||
<link rel="stylesheet"
|
||||
href="chrome://browser/content/feeds/subscribe.css"
|
||||
type="text/css"
|
||||
media="all"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/feeds/subscribe.js"/>
|
||||
</head>
|
||||
|
@ -34,30 +37,8 @@
|
|||
<p id="feedSubscriptionInfo1" />
|
||||
<p id="feedSubscriptionInfo2" />
|
||||
</div>
|
||||
|
||||
<!-- XXXmano this can't have any whitespace in it. Otherwise you would see
|
||||
how much XUL-in-XHTML sucks, see bug 348830 -->
|
||||
<div id="feedSubscribeLine"
|
||||
><xul:vbox
|
||||
><xul:hbox align="center"
|
||||
><xul:description id="subscribeUsingDescription"
|
||||
/><xul:menulist id="handlersMenuList" aria-labelledby="subscribeUsingDescription"
|
||||
><xul:menupopup menugenerated="true" id="handlersMenuPopup"
|
||||
><xul:menuitem id="liveBookmarksMenuItem" label="&feedLiveBookmarks;" class="menuitem-iconic" image="chrome://browser/skin/page-livemarks.png" selected="true"
|
||||
/><xul:menuseparator
|
||||
/></xul:menupopup
|
||||
></xul:menulist
|
||||
></xul:hbox
|
||||
><xul:hbox
|
||||
><xul:checkbox id="alwaysUse" checked="false"
|
||||
/></xul:hbox
|
||||
><xul:hbox align="center"
|
||||
><xul:spacer flex="1"
|
||||
/><xul:button label="&feedSubscribeNow;" id="subscribeButton"
|
||||
/></xul:hbox
|
||||
></xul:vbox
|
||||
></div
|
||||
></div>
|
||||
<div id="feedSubscribeLine"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is mozilla.org code.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Mozilla Foundation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 2010
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
- in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
- of those above. If you wish to allow use of your version of this file only
|
||||
- under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
- use your version of this file under the terms of the MPL, indicate your
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the LGPL or the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE bindings [
|
||||
<!ENTITY % feedDTD
|
||||
SYSTEM "chrome://browser/locale/feeds/subscribe.dtd">
|
||||
%feedDTD;
|
||||
]>
|
||||
<bindings id="feedBindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<binding id="feedreaderUI">
|
||||
<content>
|
||||
<xul:vbox>
|
||||
<xul:hbox align="center">
|
||||
<xul:description anonid="subscribeUsingDescription" class="subscribeUsingDescription"/>
|
||||
<xul:menulist anonid="handlersMenuList" class="handlersMenuList" aria-labelledby="subscribeUsingDescription">
|
||||
<xul:menupopup menugenerated="true" anonid="handlersMenuPopup" class="handlersMenuPopup">
|
||||
<xul:menuitem anonid="liveBookmarksMenuItem" label="&feedLiveBookmarks;" class="menuitem-iconic liveBookmarksMenuItem" image="chrome://browser/skin/page-livemarks.png" selected="true"/>
|
||||
<xul:menuseparator/>
|
||||
</xul:menupopup>
|
||||
</xul:menulist>
|
||||
</xul:hbox>
|
||||
<xul:hbox>
|
||||
<xul:checkbox anonid="alwaysUse" class="alwaysUse" checked="false"/>
|
||||
</xul:hbox>
|
||||
<xul:hbox align="center">
|
||||
<xul:spacer flex="1"/>
|
||||
<xul:button label="&feedSubscribeNow;" anonid="subscribeButton" class="subscribeButton"/>
|
||||
</xul:hbox>
|
||||
</xul:vbox>
|
||||
</content>
|
||||
<resources>
|
||||
<stylesheet src="chrome://browser/skin/feeds/subscribe-ui.css"/>
|
||||
</resources>
|
||||
</binding>
|
||||
</bindings>
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
browser.jar:
|
||||
* content/browser/feeds/subscribe.xhtml (content/subscribe.xhtml)
|
||||
* content/browser/feeds/subscribe.js (content/subscribe.js)
|
||||
* content/browser/feeds/subscribe.xml (content/subscribe.xml)
|
||||
content/browser/feeds/subscribe.css (content/subscribe.css)
|
||||
|
|
|
@ -730,6 +730,15 @@ FeedWriter.prototype = {
|
|||
Cu.evalInSandbox(codeStr, this._contentSandbox);
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper method to get an element in the XBL binding where the handler
|
||||
* selection UI lives
|
||||
*/
|
||||
_getUIElement: function FW__getUIElement(id) {
|
||||
return this._document.getAnonymousElementByAttribute(
|
||||
this._document.getElementById("feedSubscribeLine"), "anonid", id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays a prompt from which the user may choose a (client) feed reader.
|
||||
* @return - true if a feed reader was selected, false otherwise.
|
||||
|
@ -775,7 +784,7 @@ FeedWriter.prototype = {
|
|||
},
|
||||
|
||||
_setAlwaysUseCheckedState: function FW__setAlwaysUseCheckedState(feedType) {
|
||||
var checkbox = this._document.getElementById("alwaysUse");
|
||||
var checkbox = this._getUIElement("alwaysUse");
|
||||
if (checkbox) {
|
||||
var alwaysUse = false;
|
||||
try {
|
||||
|
@ -802,18 +811,17 @@ FeedWriter.prototype = {
|
|||
}
|
||||
|
||||
this._contentSandbox.subscribeUsing =
|
||||
this._document.getElementById("subscribeUsingDescription");
|
||||
this._getUIElement("subscribeUsingDescription");
|
||||
this._contentSandbox.label = this._getString(stringLabel);
|
||||
var codeStr = "subscribeUsing.setAttribute('value', label);"
|
||||
Cu.evalInSandbox(codeStr, this._contentSandbox);
|
||||
},
|
||||
|
||||
_setAlwaysUseLabel: function FW__setAlwaysUseLabel() {
|
||||
var checkbox = this._document.getElementById("alwaysUse");
|
||||
var checkbox = this._getUIElement("alwaysUse");
|
||||
if (checkbox) {
|
||||
var handlersMenuList = this._document.getElementById("handlersMenuList");
|
||||
if (handlersMenuList) {
|
||||
var handlerName = this._getSelectedItemFromMenulist(handlersMenuList)
|
||||
if (this._handlersMenuList) {
|
||||
var handlerName = this._getSelectedItemFromMenulist(this._handlersMenuList)
|
||||
.getAttribute("label");
|
||||
var stringLabel = "alwaysUseForFeeds";
|
||||
switch (this._getFeedType()) {
|
||||
|
@ -843,7 +851,7 @@ FeedWriter.prototype = {
|
|||
}
|
||||
|
||||
if (event.type == "command") {
|
||||
switch (event.target.id) {
|
||||
switch (event.target.getAttribute("anonid")) {
|
||||
case "subscribeButton":
|
||||
this.subscribe();
|
||||
break;
|
||||
|
@ -856,8 +864,7 @@ FeedWriter.prototype = {
|
|||
* selected). If we don't show the filepicker here, it will be shown
|
||||
* when clicking "Subscribe Now".
|
||||
*/
|
||||
var popupbox = this._document.getElementById("handlersMenuList")
|
||||
.firstChild.boxObject;
|
||||
var popupbox = this._handlersMenuList.firstChild.boxObject;
|
||||
popupbox.QueryInterface(Components.interfaces.nsIPopupBoxObject);
|
||||
if (popupbox.popupState == "hiding" && !this._chooseClientApp()) {
|
||||
// Select the (per-prefs) selected handler if no application was
|
||||
|
@ -884,11 +891,10 @@ FeedWriter.prototype = {
|
|||
|
||||
switch (handler) {
|
||||
case "web": {
|
||||
var handlersMenuList = this._document.getElementById("handlersMenuList");
|
||||
if (handlersMenuList) {
|
||||
if (this._handlersMenuList) {
|
||||
var url = prefs.getComplexValue(getPrefWebForType(feedType), Ci.nsISupportsString).data;
|
||||
var handlers =
|
||||
handlersMenuList.getElementsByAttribute("webhandlerurl", url);
|
||||
this._handlersMenuList.getElementsByAttribute("webhandlerurl", url);
|
||||
if (handlers.length == 0) {
|
||||
LOG("FeedWriter._setSelectedHandler: selected web handler isn't in the menulist")
|
||||
return;
|
||||
|
@ -926,7 +932,7 @@ FeedWriter.prototype = {
|
|||
}
|
||||
case "bookmarks":
|
||||
default: {
|
||||
var liveBookmarksMenuItem = this._document.getElementById("liveBookmarksMenuItem");
|
||||
var liveBookmarksMenuItem = this._getUIElement("liveBookmarksMenuItem");
|
||||
if (liveBookmarksMenuItem)
|
||||
this._safeDoCommand(liveBookmarksMenuItem);
|
||||
}
|
||||
|
@ -934,7 +940,7 @@ FeedWriter.prototype = {
|
|||
},
|
||||
|
||||
_initSubscriptionUI: function FW__initSubscriptionUI() {
|
||||
var handlersMenuPopup = this._document.getElementById("handlersMenuPopup");
|
||||
var handlersMenuPopup = this._getUIElement("handlersMenuPopup");
|
||||
if (!handlersMenuPopup)
|
||||
return;
|
||||
|
||||
|
@ -957,11 +963,13 @@ FeedWriter.prototype = {
|
|||
codeStr = "header.className = 'feedBackground'; ";
|
||||
}
|
||||
|
||||
var liveBookmarksMenuItem = this._getUIElement("liveBookmarksMenuItem");
|
||||
|
||||
// Last-selected application
|
||||
var menuItem = this._document.createElementNS(XUL_NS, "menuitem");
|
||||
menuItem.id = "selectedAppMenuItem";
|
||||
menuItem.className = "menuitem-iconic";
|
||||
var menuItem = liveBookmarksMenuItem.cloneNode(false);
|
||||
menuItem.removeAttribute("selected");
|
||||
menuItem.setAttribute("anonid", "selectedAppMenuItem");
|
||||
menuItem.className = "menuitem-iconic selectedAppMenuItem";
|
||||
menuItem.setAttribute("handlerType", "client");
|
||||
try {
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
|
@ -990,9 +998,10 @@ FeedWriter.prototype = {
|
|||
this._defaultSystemReader = Cc["@mozilla.org/browser/shell-service;1"].
|
||||
getService(Ci.nsIShellService).
|
||||
defaultFeedReader;
|
||||
menuItem = this._document.createElementNS(XUL_NS, "menuitem");
|
||||
menuItem.id = "defaultHandlerMenuItem";
|
||||
menuItem.className = "menuitem-iconic";
|
||||
menuItem = liveBookmarksMenuItem.cloneNode(false);
|
||||
menuItem.removeAttribute("selected");
|
||||
menuItem.setAttribute("anonid", "defaultHandlerMenuItem");
|
||||
menuItem.className = "menuitem-iconic defaultHandlerMenuItem";
|
||||
menuItem.setAttribute("handlerType", "client");
|
||||
|
||||
this._initMenuItemWithFile(menuItem, this._defaultSystemReader);
|
||||
|
@ -1011,9 +1020,10 @@ FeedWriter.prototype = {
|
|||
}
|
||||
|
||||
// "Choose Application..." menuitem
|
||||
menuItem = this._document.createElementNS(XUL_NS, "menuitem");
|
||||
menuItem.id = "chooseApplicationMenuItem";
|
||||
menuItem.className = "menuitem-iconic";
|
||||
menuItem = liveBookmarksMenuItem.cloneNode(false);
|
||||
menuItem.removeAttribute("selected");
|
||||
menuItem.setAttribute("anonid", "chooseApplicationMenuItem");
|
||||
menuItem.className = "menuitem-iconic chooseApplicationMenuItem";
|
||||
menuItem.setAttribute("label", this._getString("chooseApplicationMenuItem"));
|
||||
|
||||
this._contentSandbox.chooseAppMenuItem = menuItem;
|
||||
|
@ -1021,7 +1031,7 @@ FeedWriter.prototype = {
|
|||
|
||||
// separator
|
||||
this._contentSandbox.chooseAppSep =
|
||||
this._document.createElementNS(XUL_NS, "menuseparator")
|
||||
menuItem = liveBookmarksMenuItem.nextSibling.cloneNode(false);
|
||||
codeStr += "handlersMenuPopup.appendChild(chooseAppSep); ";
|
||||
|
||||
Cu.evalInSandbox(codeStr, this._contentSandbox);
|
||||
|
@ -1036,7 +1046,8 @@ FeedWriter.prototype = {
|
|||
var handlers = wccr.getContentHandlers(this._getMimeTypeForFeedType(feedType));
|
||||
if (handlers.length != 0) {
|
||||
for (var i = 0; i < handlers.length; ++i) {
|
||||
menuItem = this._document.createElementNS(XUL_NS, "menuitem");
|
||||
menuItem = liveBookmarksMenuItem.cloneNode(false);
|
||||
menuItem.removeAttribute("selected");
|
||||
menuItem.className = "menuitem-iconic";
|
||||
menuItem.setAttribute("label", handlers[i].name);
|
||||
menuItem.setAttribute("handlerType", "web");
|
||||
|
@ -1072,8 +1083,7 @@ FeedWriter.prototype = {
|
|||
handlersMenuPopup.addEventListener("command", this, false);
|
||||
|
||||
// Set up the "Subscribe Now" button
|
||||
this._document
|
||||
.getElementById("subscribeButton")
|
||||
this._getUIElement("subscribeButton")
|
||||
.addEventListener("command", this, false);
|
||||
|
||||
// first-run ui
|
||||
|
@ -1139,6 +1149,7 @@ FeedWriter.prototype = {
|
|||
_document: null,
|
||||
_feedURI: null,
|
||||
_feedPrincipal: null,
|
||||
_handlersMenuList: null,
|
||||
|
||||
// nsIFeedWriter
|
||||
init: function FW_init(aWindow) {
|
||||
|
@ -1149,6 +1160,8 @@ FeedWriter.prototype = {
|
|||
|
||||
this._window = window;
|
||||
this._document = window.document;
|
||||
this._document.getElementById("feedSubscribeLine").offsetTop;
|
||||
this._handlersMenuList = this._getUIElement("handlersMenuList");
|
||||
|
||||
var secman = Cc["@mozilla.org/scriptsecuritymanager;1"].
|
||||
getService(Ci.nsIScriptSecurityManager);
|
||||
|
@ -1195,11 +1208,9 @@ FeedWriter.prototype = {
|
|||
},
|
||||
|
||||
close: function FW_close() {
|
||||
this._document
|
||||
.getElementById("handlersMenuPopup")
|
||||
this._getUIElement("handlersMenuPopup")
|
||||
.removeEventListener("command", this, false);
|
||||
this._document
|
||||
.getElementById("subscribeButton")
|
||||
this._getUIElement("subscribeButton")
|
||||
.removeEventListener("command", this, false);
|
||||
this._document = null;
|
||||
this._window = null;
|
||||
|
@ -1246,19 +1257,17 @@ FeedWriter.prototype = {
|
|||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
var defaultHandler = "reader";
|
||||
var useAsDefault = this._document.getElementById("alwaysUse")
|
||||
.getAttribute("checked");
|
||||
var useAsDefault = this._getUIElement("alwaysUse").getAttribute("checked");
|
||||
|
||||
var handlersMenuList = this._document.getElementById("handlersMenuList");
|
||||
var selectedItem = this._getSelectedItemFromMenulist(handlersMenuList);
|
||||
var selectedItem = this._getSelectedItemFromMenulist(this._handlersMenuList);
|
||||
|
||||
// Show the file picker before subscribing if the
|
||||
// choose application menuitem was chosen using the keyboard
|
||||
if (selectedItem.id == "chooseApplicationMenuItem") {
|
||||
if (selectedItem.getAttribute("anonid") == "chooseApplicationMenuItem") {
|
||||
if (!this._chooseClientApp())
|
||||
return;
|
||||
|
||||
selectedItem = this._getSelectedItemFromMenulist(handlersMenuList);
|
||||
selectedItem = this._getSelectedItemFromMenulist(this._handlersMenuList);
|
||||
}
|
||||
|
||||
if (selectedItem.hasAttribute("webhandlerurl")) {
|
||||
|
@ -1282,7 +1291,7 @@ FeedWriter.prototype = {
|
|||
}
|
||||
}
|
||||
else {
|
||||
switch (selectedItem.id) {
|
||||
switch (selectedItem.getAttribute("anonid")) {
|
||||
case "selectedAppMenuItem":
|
||||
prefs.setComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile,
|
||||
this._selectedApp);
|
||||
|
@ -1389,8 +1398,7 @@ FeedWriter.prototype = {
|
|||
// Go through the readers menu and look for the corresponding
|
||||
// reader menu-item for the page if any.
|
||||
var spec = aURI.spec;
|
||||
var handlersMenulist = this._document.getElementById("handlersMenuList");
|
||||
var possibleHandlers = handlersMenulist.firstChild.childNodes;
|
||||
var possibleHandlers = this._handlersMenuList.firstChild.childNodes;
|
||||
for (var i=0; i < possibleHandlers.length ; i++) {
|
||||
if (possibleHandlers[i].getAttribute("webhandlerurl") == spec) {
|
||||
this._setFaviconForWebReader(aURI, possibleHandlers[i]);
|
||||
|
|
|
@ -438,7 +438,7 @@ BrowserGlue.prototype = {
|
|||
var browser = browserEnum.getNext();
|
||||
var tabbrowser = browser.document.getElementById("content");
|
||||
if (tabbrowser)
|
||||
pagecount += tabbrowser.browsers.length;
|
||||
pagecount += tabbrowser.browsers.length - tabbrowser._numPinnedTabs;
|
||||
}
|
||||
|
||||
this._saveSession = false;
|
||||
|
@ -469,7 +469,7 @@ BrowserGlue.prototype = {
|
|||
getService(Ci.nsIPrivateBrowsingService).
|
||||
privateBrowsingEnabled;
|
||||
if (!showPrompt || inPrivateBrowsing)
|
||||
return false;
|
||||
return;
|
||||
|
||||
var quitBundle = Services.strings.createBundle("chrome://browser/locale/quitDialog.properties");
|
||||
var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
|
||||
|
|
|
@ -145,9 +145,9 @@
|
|||
|
||||
<!-- Start Private Browsing -->
|
||||
<div id="startPrivateBrowsingDesc" class="showNormal">
|
||||
<button xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="startPrivateBrowsing" label="&privatebrowsingpage.startPrivateBrowsing.label;"
|
||||
accesskey="&privatebrowsingpage.startPrivateBrowsing.accesskey;"/>
|
||||
<button id="startPrivateBrowsing"
|
||||
accesskey="&privatebrowsingpage.startPrivateBrowsing.accesskey;"
|
||||
>&privatebrowsingpage.startPrivateBrowsing.label;</button>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
|
|
|
@ -212,15 +212,12 @@
|
|||
<!-- Action buttons -->
|
||||
<div id="buttons">
|
||||
<!-- Commands handled in browser.js -->
|
||||
<xul:button xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="getMeOutButton" label="&safeb.palm.accept.label;"/>
|
||||
<xul:button xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="reportButton" label="&safeb.palm.reportPage.label;"/>
|
||||
<button id="getMeOutButton">&safeb.palm.accept.label;</button>
|
||||
<button id="reportButton">&safeb.palm.reportPage.label;</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="ignoreWarning">
|
||||
<xul:button xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="ignoreWarningButton" label="&safeb.palm.decline.label;"/>
|
||||
<button id="ignoreWarningButton">&safeb.palm.decline.label;</button>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
|
|
|
@ -19,7 +19,7 @@ function testMalware() {
|
|||
ok(el, "Ignore warning button should be present for malware");
|
||||
|
||||
var style = content.getComputedStyle(el, null);
|
||||
is(style.display, "-moz-box", "Ignore Warning button should be display:-moz-box for malware");
|
||||
is(style.display, "inline", "Ignore Warning button should be display:inline for malware");
|
||||
|
||||
// Now launch the phishing test
|
||||
window.addEventListener("DOMContentLoaded", testPhishing, true);
|
||||
|
@ -33,7 +33,7 @@ function testPhishing() {
|
|||
ok(el, "Ignore warning button should be present for phishing");
|
||||
|
||||
var style = content.getComputedStyle(el, null);
|
||||
is(style.display, "-moz-box", "Ignore Warning button should be display:-moz-box for phishing");
|
||||
is(style.display, "inline", "Ignore Warning button should be display:inline for phishing");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
|
|
|
@ -157,7 +157,14 @@ SessionStartup.prototype = {
|
|||
|
||||
if (this._sessionType != Ci.nsISessionStartup.NO_SESSION) {
|
||||
// wait for the first browser window to open
|
||||
Services.obs.addObserver(this, "domwindowopened", true);
|
||||
|
||||
// Don't reset the initial window's default args (i.e. the home page(s))
|
||||
// if all stored tabs are pinned.
|
||||
if (!initialState.windows ||
|
||||
!initialState.windows.every(function (win)
|
||||
win.tabs.every(function (tab) tab.pinned)))
|
||||
Services.obs.addObserver(this, "domwindowopened", true);
|
||||
|
||||
Services.obs.addObserver(this, "browser:purge-session-history", true);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -198,10 +198,8 @@ SessionStoreService.prototype = {
|
|||
// whether we clearing history on shutdown
|
||||
_clearingOnShutdown: false,
|
||||
|
||||
#ifndef XP_MACOSX
|
||||
// whether the last window was closed and should be restored
|
||||
_restoreLastWindow: false,
|
||||
#endif
|
||||
|
||||
/* ........ Global Event Handlers .............. */
|
||||
|
||||
|
@ -290,10 +288,8 @@ SessionStoreService.prototype = {
|
|||
catch (ex) { debug("The session file is invalid: " + ex); }
|
||||
}
|
||||
|
||||
// remove the session data files if crash recovery is disabled
|
||||
if (!this._resume_from_crash)
|
||||
this._clearDisk();
|
||||
else { // create a backup if the session data file exists
|
||||
if (this._resume_from_crash) {
|
||||
// create a backup if the session data file exists
|
||||
try {
|
||||
if (this._sessionFileBackup.exists())
|
||||
this._sessionFileBackup.remove(false);
|
||||
|
@ -318,12 +314,14 @@ SessionStoreService.prototype = {
|
|||
* quit-application-granted, quit-application
|
||||
*/
|
||||
_uninit: function sss_uninit() {
|
||||
if (this._doResumeSession()) { // save all data for session resuming
|
||||
this.saveState(true);
|
||||
}
|
||||
else { // discard all session related data
|
||||
// save all data for session resuming
|
||||
this.saveState(true);
|
||||
|
||||
if (!this._doResumeSession()) {
|
||||
// discard all session related data
|
||||
this._clearDisk();
|
||||
}
|
||||
|
||||
// Make sure to break our cycle with the save timer
|
||||
if (this._saveTimer) {
|
||||
this._saveTimer.cancel();
|
||||
|
@ -359,15 +357,13 @@ SessionStoreService.prototype = {
|
|||
// freeze the data at what we've got (ignoring closing windows)
|
||||
this._loadState = STATE_QUITTING;
|
||||
break;
|
||||
#ifndef XP_MACOSX
|
||||
case "browser-lastwindow-close-granted":
|
||||
// last browser window is quitting.
|
||||
// remember to restore the last window when another browser window is openend
|
||||
// remember to restore the last window when another browser window is opened
|
||||
// do not account for pref(resume_session_once) at this point, as it might be
|
||||
// set by another observer getting this notice after us
|
||||
this._restoreLastWindow = true;
|
||||
break;
|
||||
#endif
|
||||
case "quit-application":
|
||||
if (aData == "restart") {
|
||||
this._prefBranch.setBoolPref("sessionstore.resume_session_once", true);
|
||||
|
@ -481,10 +477,9 @@ SessionStoreService.prototype = {
|
|||
this._resume_from_crash = this._prefBranch.getBoolPref("sessionstore.resume_from_crash");
|
||||
// either create the file with crash recovery information or remove it
|
||||
// (when _loadState is not STATE_RUNNING, that file is used for session resuming instead)
|
||||
if (this._resume_from_crash)
|
||||
this.saveState(true);
|
||||
else if (this._loadState == STATE_RUNNING)
|
||||
if (!this._resume_from_crash)
|
||||
this._clearDisk();
|
||||
this.saveState(true);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -611,7 +606,8 @@ SessionStoreService.prototype = {
|
|||
// make sure that the restored tabs are first in the window
|
||||
this._initialState._firstTabs = true;
|
||||
this._restoreCount = this._initialState.windows ? this._initialState.windows.length : 0;
|
||||
this.restoreWindow(aWindow, this._initialState, this._isCmdLineEmpty(aWindow));
|
||||
this.restoreWindow(aWindow, this._initialState,
|
||||
this._isCmdLineEmpty(aWindow, this._initialState));
|
||||
delete this._initialState;
|
||||
|
||||
// _loadState changed from "stopped" to "running"
|
||||
|
@ -631,15 +627,13 @@ SessionStoreService.prototype = {
|
|||
let followUp = this._statesToRestore[aWindow.__SS_restoreID].windows.length == 1;
|
||||
this.restoreWindow(aWindow, this._statesToRestore[aWindow.__SS_restoreID], true, followUp);
|
||||
}
|
||||
#ifndef XP_MACOSX
|
||||
else if (this._restoreLastWindow && aWindow.toolbar.visible &&
|
||||
this._closedWindows.length && this._doResumeSession() &&
|
||||
this._closedWindows.length &&
|
||||
!this._inPrivateBrowsing) {
|
||||
|
||||
// default to the most-recently closed window
|
||||
// don't use popup windows
|
||||
let state = null;
|
||||
this._closedWindows = this._closedWindows.filter(function(aWinState) {
|
||||
let newClosedWindows = this._closedWindows.filter(function(aWinState) {
|
||||
if (!state && !aWinState.isPopup) {
|
||||
state = aWinState;
|
||||
return false;
|
||||
|
@ -648,9 +642,16 @@ SessionStoreService.prototype = {
|
|||
});
|
||||
if (state) {
|
||||
delete state.hidden;
|
||||
state = { windows: [state] };
|
||||
this._restoreCount = 1;
|
||||
this.restoreWindow(aWindow, state, this._isCmdLineEmpty(aWindow));
|
||||
#ifndef XP_MACOSX
|
||||
if (!this._doResumeSession())
|
||||
#endif
|
||||
state.tabs = state.tabs.filter(function (tab) tab.pinned);
|
||||
if (state.tabs.length > 0) {
|
||||
this._closedWindows = newClosedWindows;
|
||||
this._restoreCount = 1;
|
||||
state = { windows: [state] };
|
||||
this.restoreWindow(aWindow, state, this._isCmdLineEmpty(aWindow, state));
|
||||
}
|
||||
}
|
||||
// we actually restored the session just now.
|
||||
this._prefBranch.setBoolPref("sessionstore.resume_session_once", false);
|
||||
|
@ -661,7 +662,6 @@ SessionStoreService.prototype = {
|
|||
// undoCloseWindow was executed.
|
||||
this._restoreLastWindow = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
var tabbrowser = aWindow.gBrowser;
|
||||
|
||||
|
@ -1140,14 +1140,19 @@ SessionStoreService.prototype = {
|
|||
* Store all session data for a window
|
||||
* @param aWindow
|
||||
* Window reference
|
||||
* @param aPinnedOnly
|
||||
* Bool collect pinned tabs only
|
||||
*/
|
||||
_saveWindowHistory: function sss_saveWindowHistory(aWindow) {
|
||||
_saveWindowHistory: function sss_saveWindowHistory(aWindow, aPinnedOnly) {
|
||||
var tabbrowser = aWindow.gBrowser;
|
||||
var tabs = tabbrowser.tabs;
|
||||
var tabsData = this._windows[aWindow.__SSi].tabs = [];
|
||||
|
||||
for (var i = 0; i < tabs.length; i++)
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
if (aPinnedOnly && !tabs[i].pinned)
|
||||
break;
|
||||
tabsData.push(this._collectTabData(tabs[i]));
|
||||
}
|
||||
|
||||
this._windows[aWindow.__SSi].selected = tabbrowser.mTabBox.selectedIndex + 1;
|
||||
},
|
||||
|
@ -1435,16 +1440,15 @@ SessionStoreService.prototype = {
|
|||
*/
|
||||
_updateTextAndScrollData: function sss_updateTextAndScrollData(aWindow) {
|
||||
var browsers = aWindow.gBrowser.browsers;
|
||||
for (var i = 0; i < browsers.length; i++) {
|
||||
this._windows[aWindow.__SSi].tabs.forEach(function (tabData, i) {
|
||||
if (browsers[i].__SS_data &&
|
||||
browsers[i].__SS_data._tabStillLoading)
|
||||
return; // ignore incompletely initialized tabs
|
||||
try {
|
||||
var tabData = this._windows[aWindow.__SSi].tabs[i];
|
||||
if (browsers[i].__SS_data &&
|
||||
browsers[i].__SS_data._tabStillLoading)
|
||||
continue; // ignore incompletely initialized tabs
|
||||
this._updateTextAndScrollDataForTab(aWindow, browsers[i], tabData);
|
||||
}
|
||||
catch (ex) { debug(ex); } // get as much data as possible, ignore failures (might succeed the next time)
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1751,12 +1755,14 @@ SessionStoreService.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* serialize session data as Ini-formatted string
|
||||
* gather session data as object
|
||||
* @param aUpdateAll
|
||||
* Bool update all windows
|
||||
* @returns string
|
||||
* @param aPinnedOnly
|
||||
* Bool collect pinned tabs only
|
||||
* @returns object
|
||||
*/
|
||||
_getCurrentState: function sss_getCurrentState(aUpdateAll) {
|
||||
_getCurrentState: function sss_getCurrentState(aUpdateAll, aPinnedOnly) {
|
||||
this._handleClosedWindows();
|
||||
|
||||
var activeWindow = this._getMostRecentBrowserWindow();
|
||||
|
@ -1767,7 +1773,7 @@ SessionStoreService.prototype = {
|
|||
if (!this._isWindowLoaded(aWindow)) // window data is still in _statesToRestore
|
||||
return;
|
||||
if (aUpdateAll || this._dirtyWindows[aWindow.__SSi] || aWindow == activeWindow) {
|
||||
this._collectWindowData(aWindow);
|
||||
this._collectWindowData(aWindow, aPinnedOnly);
|
||||
}
|
||||
else { // always update the window features (whose change alone never triggers a save operation)
|
||||
this._updateWindowFeatures(aWindow);
|
||||
|
@ -1813,6 +1819,17 @@ SessionStoreService.prototype = {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (aPinnedOnly) {
|
||||
total = total.filter(function (win) {
|
||||
win.tabs = win.tabs.filter(function (tab) tab.pinned);
|
||||
return win.tabs.length > 0;
|
||||
});
|
||||
if (total.length == 0)
|
||||
return null;
|
||||
|
||||
lastClosedWindowsCopy = [];
|
||||
}
|
||||
|
||||
if (activeWindow) {
|
||||
this.activeWindowSSiCache = activeWindow.__SSi || "";
|
||||
}
|
||||
|
@ -1844,12 +1861,12 @@ SessionStoreService.prototype = {
|
|||
return { windows: total };
|
||||
},
|
||||
|
||||
_collectWindowData: function sss_collectWindowData(aWindow) {
|
||||
_collectWindowData: function sss_collectWindowData(aWindow, aPinnedOnly) {
|
||||
if (!this._isWindowLoaded(aWindow))
|
||||
return;
|
||||
|
||||
// update the internal state data for this window
|
||||
this._saveWindowHistory(aWindow);
|
||||
this._saveWindowHistory(aWindow, aPinnedOnly);
|
||||
this._updateTextAndScrollData(aWindow);
|
||||
this._updateCookieHosts(aWindow);
|
||||
this._updateWindowFeatures(aWindow);
|
||||
|
@ -2561,8 +2578,7 @@ SessionStoreService.prototype = {
|
|||
this._dirtyWindows[aWindow.__SSi] = true;
|
||||
}
|
||||
|
||||
if (!this._saveTimer && this._resume_from_crash &&
|
||||
!this._inPrivateBrowsing) {
|
||||
if (!this._saveTimer && !this._inPrivateBrowsing) {
|
||||
// interval until the next disk operation is allowed
|
||||
var minimalDelay = this._lastSaveTime + this._interval - Date.now();
|
||||
|
||||
|
@ -2584,15 +2600,23 @@ SessionStoreService.prototype = {
|
|||
* Bool update all windows
|
||||
*/
|
||||
saveState: function sss_saveState(aUpdateAll) {
|
||||
// if crash recovery is disabled, only save session resuming information
|
||||
if (!this._resume_from_crash && this._loadState == STATE_RUNNING)
|
||||
return;
|
||||
|
||||
// if we're in private browsing mode, do nothing
|
||||
if (this._inPrivateBrowsing)
|
||||
return;
|
||||
|
||||
var oState = this._getCurrentState(aUpdateAll);
|
||||
var pinnedOnly = false;
|
||||
if (this._loadState == STATE_QUITTING && !this._doResumeSession() ||
|
||||
/* if crash recovery is disabled, only save session resuming information */
|
||||
this._loadState == STATE_RUNNING && !this._resume_from_crash)
|
||||
pinnedOnly = true;
|
||||
|
||||
var oState = this._getCurrentState(aUpdateAll, pinnedOnly);
|
||||
if (!oState)
|
||||
return;
|
||||
|
||||
if (pinnedOnly)
|
||||
this._prefBranch.setBoolPref("sessionstore.resume_session_once", true);
|
||||
|
||||
oState.session = {
|
||||
state: this._loadState == STATE_RUNNING ? STATE_RUNNING_STR : STATE_STOPPED_STR,
|
||||
lastUpdate: Date.now()
|
||||
|
@ -2756,12 +2780,19 @@ SessionStoreService.prototype = {
|
|||
* C.f.: nsBrowserContentHandler's defaultArgs implementation.
|
||||
* @returns bool
|
||||
*/
|
||||
_isCmdLineEmpty: function sss_isCmdLineEmpty(aWindow) {
|
||||
var defaultArgs = Cc["@mozilla.org/browser/clh;1"].
|
||||
getService(Ci.nsIBrowserHandler).defaultArgs;
|
||||
if (aWindow.arguments && aWindow.arguments[0] &&
|
||||
aWindow.arguments[0] == defaultArgs)
|
||||
aWindow.arguments[0] = null;
|
||||
_isCmdLineEmpty: function sss_isCmdLineEmpty(aWindow, aState) {
|
||||
var pinnedOnly = aState.windows &&
|
||||
aState.windows.every(function (win)
|
||||
win.tabs.every(function (tab) tab.pinned));
|
||||
|
||||
if (!pinnedOnly) {
|
||||
let defaultArgs = Cc["@mozilla.org/browser/clh;1"].
|
||||
getService(Ci.nsIBrowserHandler).defaultArgs;
|
||||
if (aWindow.arguments &&
|
||||
aWindow.arguments[0] &&
|
||||
aWindow.arguments[0] == defaultArgs)
|
||||
aWindow.arguments[0] = null;
|
||||
}
|
||||
|
||||
return !aWindow.arguments || !aWindow.arguments[0];
|
||||
},
|
||||
|
|
|
@ -114,6 +114,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_524745.js \
|
||||
browser_528776.js \
|
||||
browser_579879.js \
|
||||
browser_580512.js \
|
||||
browser_586147.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -485,7 +485,7 @@ function test() {
|
|||
|
||||
/**
|
||||
* Test 8: Test if closing can be denied on Mac
|
||||
* Futhermore prepares the testNotificationCount test (Test 6)
|
||||
* Futhermore prepares the testNotificationCount test (Test 7)
|
||||
* @note: Mac only
|
||||
*/
|
||||
function testMacNotifications(nextFn, iteration) {
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
const URIS_PINNED = ["about:license", "about:about"];
|
||||
const URIS_NORMAL_A = ["about:mozilla"];
|
||||
const URIS_NORMAL_B = ["about:buildconfig"];
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
isnot(Services.prefs.getIntPref("browser.startup.page"), 3,
|
||||
"pref to save session must not be set for this test");
|
||||
ok(!Services.prefs.getBoolPref("browser.sessionstore.resume_session_once"),
|
||||
"pref to save session once must not be set for this test");
|
||||
|
||||
document.documentElement.setAttribute("windowtype", "navigator:browsertestdummy");
|
||||
|
||||
openWinWithCb(closeFirstWin, URIS_PINNED.concat(URIS_NORMAL_A));
|
||||
}
|
||||
|
||||
function closeFirstWin(win) {
|
||||
win.gBrowser.pinTab(win.gBrowser.tabs[0]);
|
||||
win.gBrowser.pinTab(win.gBrowser.tabs[1]);
|
||||
win.BrowserTryToCloseWindow();
|
||||
ok(win.closed, "window closed");
|
||||
|
||||
openWinWithCb(checkSecondWin, URIS_NORMAL_B, URIS_PINNED.concat(URIS_NORMAL_B));
|
||||
}
|
||||
|
||||
function checkSecondWin(win) {
|
||||
is(win.gBrowser.browsers[0].currentURI.spec, URIS_PINNED[0], "first pinned tab restored");
|
||||
is(win.gBrowser.browsers[1].currentURI.spec, URIS_PINNED[1], "second pinned tab restored");
|
||||
ok(win.gBrowser.tabs[0].pinned, "first pinned tab is still pinned");
|
||||
ok(win.gBrowser.tabs[1].pinned, "second pinned tab is still pinned");
|
||||
win.close();
|
||||
|
||||
// cleanup
|
||||
document.documentElement.setAttribute("windowtype", "navigator:browser");
|
||||
finish();
|
||||
}
|
||||
|
||||
function openWinWithCb(cb, argURIs, expectedURIs) {
|
||||
if (!expectedURIs)
|
||||
expectedURIs = argURIs;
|
||||
|
||||
var win = openDialog("chrome://browser/content/", "_blank",
|
||||
"chrome,all,dialog=no", argURIs.join("|"));
|
||||
|
||||
win.addEventListener("load", function () {
|
||||
info("the window loaded");
|
||||
|
||||
var expectedLoads = expectedURIs.length;
|
||||
|
||||
win.gBrowser.addTabsProgressListener({
|
||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
if (aRequest &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
||||
expectedURIs.indexOf(aRequest.QueryInterface(Ci.nsIChannel).originalURI.spec) > -1 &&
|
||||
--expectedLoads <= 0) {
|
||||
win.gBrowser.removeTabsProgressListener(this);
|
||||
info("all tabs loaded");
|
||||
is(win.gBrowser.tabs.length, expectedURIs.length, "didn't load any unexpected tabs");
|
||||
executeSoon(function () {
|
||||
cb(win);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}, false);
|
||||
}
|
|
@ -650,6 +650,9 @@ xpicleanup@BIN_SUFFIX@
|
|||
modules/distribution.js
|
||||
modules/DownloadLastDir.jsm
|
||||
modules/DownloadPaths.jsm
|
||||
#ifdef XP_WIN
|
||||
modules/DownloadTaskbarProgress.jsm
|
||||
#endif
|
||||
modules/DownloadUtils.jsm
|
||||
modules/FileUtils.jsm
|
||||
modules/Geometry.jsm
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
<!ENTITY moveToGroup.label "Move to Group">
|
||||
<!ENTITY moveToGroup.accesskey "M">
|
||||
<!ENTITY moveToNewGroup.label "New Group">
|
||||
<!ENTITY moveToNewGroup.accesskey "N">
|
||||
<!ENTITY namedGroups.label "Named Groups">
|
||||
<!ENTITY bookmarkThisTab.label "Bookmark This Tab">
|
||||
<!ENTITY bookmarkThisTab.accesskey "B">
|
||||
<!ENTITY bookmarkAllTabs.label "Bookmark All Tabs…">
|
||||
|
@ -267,11 +265,12 @@
|
|||
<!ENTITY showAllHistoryCmd2.label "Show All History">
|
||||
<!ENTITY showAllHistoryCmd.commandkey "H">
|
||||
|
||||
<!ENTITY appMenuPrintCmd.label "Print">
|
||||
<!ENTITY appMenuCustomize.label "Customize">
|
||||
<!ENTITY appMenuToolbarLayout.label "Toolbar Layout…">
|
||||
<!ENTITY appMenuSidebars.label "Sidebars">
|
||||
<!ENTITY appMenuHelp.label "Help">
|
||||
<!ENTITY appMenuFind.label "Find…">
|
||||
<!ENTITY appMenuUnsorted.label "Unsorted Bookmarks">
|
||||
<!ENTITY appMenuGettingStarted.label "Getting Started">
|
||||
|
||||
<!ENTITY developerMenu.label "Developer">
|
||||
|
||||
|
|
|
@ -142,11 +142,9 @@ menuOpenAllInTabs.label=Open All in Tabs
|
|||
|
||||
# History menu
|
||||
menuRestoreAllTabs.label=Restore All Tabs
|
||||
menuRestoreAllTabs.accesskey=R
|
||||
# LOCALIZATION NOTE (menuRestoreAllWindows, menuUndoCloseWindowLabel, menuUndoCloseWindowSingleTabLabel):
|
||||
# see bug 394759
|
||||
menuRestoreAllWindows.label=Restore All Windows
|
||||
menuRestoreAllWindows.accesskey=R
|
||||
# LOCALIZATION NOTE (menuUndoCloseWindowLabel): Semi-colon list of plural forms.
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
# #1 Window Title, #2 Number of tabs
|
||||
|
|
|
@ -178,6 +178,6 @@ netError.xhtml) because it exposes functionality specific to firefox. -->
|
|||
<!ENTITY securityOverride.warningText "
|
||||
<p>You should not add an exception if you are using an internet connection that you do not trust completely or if you are not used to seeing a warning for this server.</p>
|
||||
|
||||
<xul:button xmlns:xul='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' id='getMeOutOfHereButton' label='&securityOverride.getMeOutOfHereButton;'/>
|
||||
<xul:button xmlns:xul='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' id='exceptionDialogButton' label='&securityOverride.exceptionButtonLabel;'/>
|
||||
<button id='getMeOutOfHereButton'>&securityOverride.getMeOutOfHereButton;</button>
|
||||
<button id='exceptionDialogButton'>&securityOverride.exceptionButtonLabel;</button>
|
||||
">
|
||||
|
|
|
@ -1529,9 +1529,3 @@ listitem.style-section {
|
|||
panel[dimmed="true"] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* Tab view context menu */
|
||||
|
||||
#context_tabViewMenuPopup > menuitem.group {
|
||||
-moz-padding-start: 40px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
.alwaysUse {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.handlersMenuPopup > menuitem {
|
||||
-moz-padding-start: 23px;
|
||||
}
|
||||
|
||||
.handlersMenuPopup > menuitem.menuitem-iconic {
|
||||
-moz-padding-start: 2px;
|
||||
}
|
||||
|
||||
.handlersMenuPopup > .menuitem-iconic > .menu-iconic-left {
|
||||
display: -moz-box;
|
||||
min-width: 16px;
|
||||
-moz-padding-end: 2px;
|
||||
}
|
||||
|
||||
.chooseApplicationMenuItem {
|
||||
list-style-image: url("moz-icon://dummy.exe?size=16");
|
||||
}
|
||||
|
||||
#feedHeader[dir="rtl"] .handlersMenuList > menupopup {
|
||||
direction: rtl;
|
||||
}
|
|
@ -1,8 +1,3 @@
|
|||
|
||||
*[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html {
|
||||
background: -moz-Dialog;
|
||||
font: 3mm tahoma,arial,helvetica,sans-serif;
|
||||
|
@ -67,33 +62,6 @@ html {
|
|||
padding-top: 0.2em;
|
||||
}
|
||||
|
||||
#alwaysUse {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
|
||||
#handlersMenuList > menupopup > menuitem {
|
||||
-moz-padding-start: 23px;
|
||||
}
|
||||
|
||||
#handlersMenuList > menupopup > menuitem.menuitem-iconic {
|
||||
-moz-padding-start: 2px;
|
||||
}
|
||||
|
||||
#handlersMenuList > menupopup > .menuitem-iconic > .menu-iconic-left {
|
||||
display: -moz-box;
|
||||
min-width: 16px;
|
||||
-moz-padding-end: 2px;
|
||||
}
|
||||
|
||||
#chooseApplicationMenuItem {
|
||||
list-style-image: url("moz-icon://dummy.exe?size=16");
|
||||
}
|
||||
|
||||
#feedHeader[dir="rtl"] #handlersMenuList > menupopup {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
/* Don't print subscription UI */
|
||||
@media print {
|
||||
#feedHeaderContainer {
|
||||
|
|
|
@ -42,6 +42,7 @@ browser.jar:
|
|||
skin/classic/browser/feeds/audioFeedIcon.png (feeds/audioFeedIcon.png)
|
||||
skin/classic/browser/feeds/audioFeedIcon16.png (feeds/audioFeedIcon16.png)
|
||||
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
|
||||
skin/classic/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
|
||||
skin/classic/browser/places/bookmarksMenu.png (places/bookmarksMenu.png)
|
||||
skin/classic/browser/places/bookmarksToolbar.png (places/bookmarksToolbar.png)
|
||||
skin/classic/browser/places/calendar.png (places/calendar.png)
|
||||
|
|
|
@ -2117,9 +2117,3 @@ panel[dimmed="true"] {
|
|||
#sync-status-button.statusbarpanel-iconic {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
/* Tab view context menu */
|
||||
|
||||
#context_tabViewMenuPopup > menuitem.group {
|
||||
-moz-padding-start: 40px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
.alwaysUse {
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.chooseApplicationMenuItem {
|
||||
list-style-image: url("chrome://browser/skin/preferences/application.png");
|
||||
}
|
|
@ -1,8 +1,3 @@
|
|||
|
||||
*[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html {
|
||||
background: -moz-Dialog;
|
||||
font: 3mm tahoma,arial,helvetica,sans-serif;
|
||||
|
@ -54,18 +49,10 @@ html {
|
|||
padding: 0 1em 1em 2em;
|
||||
}
|
||||
|
||||
#alwaysUse {
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
#feedHeader[firstrun="true"] #feedSubscribeLine {
|
||||
padding-left: 3.7em;
|
||||
}
|
||||
|
||||
#chooseApplicationMenuItem {
|
||||
list-style-image: url("chrome://browser/skin/preferences/application.png");
|
||||
}
|
||||
|
||||
/* Don't print subscription UI */
|
||||
@media print {
|
||||
#feedHeaderContainer {
|
||||
|
|
|
@ -55,6 +55,7 @@ browser.jar:
|
|||
skin/classic/browser/toolbarbutton-dropmarker.png
|
||||
skin/classic/browser/urlbar-favicon-glow.png
|
||||
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
|
||||
skin/classic/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
|
||||
skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)
|
||||
skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
|
||||
skin/classic/browser/feeds/videoFeedIcon.png (feeds/videoFeedIcon.png)
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 2.2 KiB |
|
@ -171,6 +171,114 @@ statusbarpanel#statusbar-display {
|
|||
color: -moz-menuhovertext;
|
||||
}
|
||||
|
||||
/* Style Firefox App Menu popup */
|
||||
|
||||
.appmenu-edit-button {
|
||||
-moz-appearance: none;
|
||||
border: 1px solid transparent;
|
||||
padding: 2px;
|
||||
background: transparent;
|
||||
-moz-border-radius: 3px;
|
||||
}
|
||||
|
||||
.appmenu-edit-button[disabled="true"] {
|
||||
opacity: .3;
|
||||
}
|
||||
|
||||
@media all and (-moz-windows-default-theme) {
|
||||
#appmenu-popup {
|
||||
-moz-appearance: none;
|
||||
background: white;
|
||||
border: 1px solid rgba(0,0,0,.5);
|
||||
}
|
||||
#appmenuPrimaryPane {
|
||||
margin-right: -1px;
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
border-right: 1px solid #c4c4c5;
|
||||
padding-left: 2px;
|
||||
}
|
||||
#appmenuSecondaryPane {
|
||||
-moz-appearance: none;
|
||||
background-color: #f1f5fb;
|
||||
-moz-box-shadow: 1px 0 3px rgb(204,214,234) inset;
|
||||
border: 0;
|
||||
padding-top: 5px;
|
||||
font-family: "Segoe UI Semibold", "Segoe UI", sans-serif;
|
||||
}
|
||||
.appmenu-edit-button:not([disabled]):hover {
|
||||
border: 1px solid #b8d6fb;
|
||||
-moz-box-shadow: inset 0 0 1px white;
|
||||
background: -moz-linear-gradient(#fafbfd, #ebf3fd);
|
||||
-moz-transition: .2s ease-in;
|
||||
}
|
||||
}
|
||||
|
||||
#appmenuSecondaryPane-spacer {
|
||||
min-height: 1em;
|
||||
}
|
||||
|
||||
#appmenu_print,
|
||||
#appmenu_print_popup,
|
||||
.appmenu-edit-button,
|
||||
#appmenu-quit {
|
||||
list-style-image: url("appmenu-icons.png");
|
||||
}
|
||||
|
||||
#appmenu-cut {
|
||||
-moz-image-region: rect(0 16px 16px 0);
|
||||
}
|
||||
|
||||
#appmenu-copy {
|
||||
-moz-image-region: rect(0 32px 16px 16px);
|
||||
}
|
||||
|
||||
#appmenu-paste {
|
||||
-moz-image-region: rect(0 48px 16px 32px);
|
||||
}
|
||||
|
||||
#appmenu_print,
|
||||
#appmenu_print_popup {
|
||||
-moz-image-region: rect(0 64px 16px 48px);
|
||||
}
|
||||
|
||||
#appmenu-quit {
|
||||
-moz-image-region: rect(0 80px 16px 64px);
|
||||
}
|
||||
|
||||
#appmenu-edit-menuitem {
|
||||
-moz-appearance: none;
|
||||
background: transparent;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#appmenu_BookmarkItem {
|
||||
list-style-image: url("chrome://browser/skin/places/bookmark.png");
|
||||
-moz-image-region: rect(0px 48px 16px 32px);
|
||||
}
|
||||
|
||||
#appmenu_privateBrowsing {
|
||||
list-style-image: url("chrome://browser/skin/Privacy-16.png");
|
||||
}
|
||||
|
||||
#appmenuBookmarkMenu_unsorted-menuitem {
|
||||
list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
|
||||
}
|
||||
|
||||
#appmenu_addons {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric-16.png");
|
||||
}
|
||||
|
||||
#appmenu-button #subscribeToPageMenuitem:not([disabled]),
|
||||
#appmenu-button #subscribeToPageMenupopup:not([hidden]) {
|
||||
list-style-image: url("chrome://browser/skin/feeds/feed-icons-16.png");
|
||||
-moz-image-region: rect(0px 16px 16px 0px);
|
||||
}
|
||||
|
||||
#appmenuBookmarkThisPage {
|
||||
list-style-image: url("chrome://browser/skin/places/bookmark.png");
|
||||
-moz-image-region: rect(0 16px 16px 0);
|
||||
}
|
||||
|
||||
/* XXX: stop-gap until the button can be drawn in the title bar */
|
||||
%ifdef WINSTRIPE_AERO
|
||||
@media not all and (-moz-windows-compositor) {
|
||||
|
@ -880,7 +988,7 @@ toolbar:not([iconsize="small"])[mode="icons"] #forward-button:not([disabled="tru
|
|||
}
|
||||
|
||||
#urlbar > .autocomplete-history-dropmarker:-moz-system-metric(touch-enabled) {
|
||||
min-width: .64cm;
|
||||
min-width: 6.4mozmm;
|
||||
}
|
||||
|
||||
#urlbar > .autocomplete-history-dropmarker:hover:active,
|
||||
|
@ -1123,7 +1231,7 @@ richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-i
|
|||
}
|
||||
|
||||
.tabbrowser-tabs:-moz-system-metric(touch-enabled) {
|
||||
min-height: .73cm;
|
||||
min-height: 7.3mozmm;
|
||||
}
|
||||
|
||||
.tabbrowser-tabs:not([overflow="true"]) {
|
||||
|
@ -1281,11 +1389,11 @@ richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-i
|
|||
#TabsToolbar > toolbarbutton,
|
||||
#TabsToolbar > toolbarpaletteitem > toolbarbutton,
|
||||
#TabsToolbar > #bookmarks-menu-button-container > #bookmarks-menu-button {
|
||||
min-width: .81cm;
|
||||
min-width: 8.1mozmm;
|
||||
}
|
||||
|
||||
.tabs-newtab-button {
|
||||
min-width: 1cm;
|
||||
min-width: 10mozmm;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1817,9 +1925,3 @@ listitem.style-section {
|
|||
panel[dimmed="true"] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* Tab view context menu */
|
||||
|
||||
#context_tabViewMenuPopup > menuitem.group {
|
||||
-moz-padding-start: 40px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
.alwaysUse {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.handlersMenuPopup > menuitem {
|
||||
-moz-padding-start: 23px;
|
||||
}
|
||||
|
||||
.handlersMenuPopup > menuitem.menuitem-iconic {
|
||||
-moz-padding-start: 2px;
|
||||
}
|
||||
|
||||
.handlersMenuPopup > .menuitem-iconic > .menu-iconic-left {
|
||||
display: -moz-box;
|
||||
min-width: 16px;
|
||||
-moz-padding-end: 2px;
|
||||
}
|
||||
|
||||
.chooseApplicationMenuItem {
|
||||
list-style-image: url("chrome://browser/skin/preferences/application.png");
|
||||
}
|
||||
|
||||
#feedHeader[dir="rtl"] .handlersMenuList > menupopup {
|
||||
direction: rtl;
|
||||
}
|
|
@ -1,8 +1,3 @@
|
|||
|
||||
*[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html {
|
||||
background: -moz-Dialog;
|
||||
font: 3mm tahoma,arial,helvetica,sans-serif;
|
||||
|
@ -33,6 +28,10 @@ html {
|
|||
color: InfoText;
|
||||
}
|
||||
|
||||
#feedIntroText {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.feedBackground {
|
||||
background: url("chrome://browser/skin/feeds/feedIcon.png") 0% 10% no-repeat InfoBackground;
|
||||
}
|
||||
|
@ -49,10 +48,6 @@ html {
|
|||
background-position: 100% 10%;
|
||||
}
|
||||
|
||||
#feedIntroText {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#feedHeader[firstrun="true"] #feedIntroText {
|
||||
padding-top: 0.1em;
|
||||
-moz-padding-start: 0.6em;
|
||||
|
@ -67,33 +62,6 @@ html {
|
|||
padding-top: 0.2em;
|
||||
}
|
||||
|
||||
#alwaysUse {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
|
||||
#handlersMenuList > menupopup > menuitem {
|
||||
-moz-padding-start: 23px;
|
||||
}
|
||||
|
||||
#handlersMenuList > menupopup > menuitem.menuitem-iconic {
|
||||
-moz-padding-start: 2px;
|
||||
}
|
||||
|
||||
#handlersMenuList > menupopup > .menuitem-iconic > .menu-iconic-left {
|
||||
display: -moz-box;
|
||||
min-width: 16px;
|
||||
-moz-padding-end: 2px;
|
||||
}
|
||||
|
||||
#chooseApplicationMenuItem {
|
||||
list-style-image: url("chrome://browser/skin/preferences/application.png");
|
||||
}
|
||||
|
||||
#feedHeader[dir="rtl"] #handlersMenuList > menupopup {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
/* Don't print subscription UI */
|
||||
@media print {
|
||||
#feedHeaderContainer {
|
||||
|
|
|
@ -12,6 +12,7 @@ browser.jar:
|
|||
skin/classic/browser/aboutSyncTabs.css
|
||||
#endif
|
||||
skin/classic/browser/actionicon-tab.png
|
||||
skin/classic/browser/appmenu-icons.png
|
||||
skin/classic/browser/appmenu-dropmarker.png
|
||||
* skin/classic/browser/browser.css (browser.css)
|
||||
* skin/classic/browser/engineManager.css (engineManager.css)
|
||||
|
@ -54,6 +55,7 @@ browser.jar:
|
|||
skin/classic/browser/feeds/videoFeedIcon.png (feeds/videoFeedIcon.png)
|
||||
skin/classic/browser/feeds/videoFeedIcon16.png (feeds/videoFeedIcon16.png)
|
||||
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
|
||||
skin/classic/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
|
||||
skin/classic/browser/places/places.css (places/places.css)
|
||||
* skin/classic/browser/places/organizer.css (places/organizer.css)
|
||||
skin/classic/browser/places/bookmark.png (places/bookmark.png)
|
||||
|
@ -125,6 +127,7 @@ browser.jar:
|
|||
#endif
|
||||
skin/classic/aero/browser/actionicon-tab.png (actionicon-tab.png)
|
||||
skin/classic/aero/browser/appmenu-dropmarker.png
|
||||
skin/classic/aero/browser/appmenu-icons.png
|
||||
* skin/classic/aero/browser/browser.css (browser-aero.css)
|
||||
* skin/classic/aero/browser/engineManager.css (engineManager.css)
|
||||
skin/classic/aero/browser/fullscreen-video.css
|
||||
|
|
|
@ -51,6 +51,7 @@ import sys
|
|||
import threading
|
||||
import tempfile
|
||||
import zipfile
|
||||
import sqlite3
|
||||
|
||||
SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
|
||||
sys.path.insert(0, SCRIPT_DIR)
|
||||
|
@ -289,6 +290,30 @@ class Automation(object):
|
|||
|
||||
return locations
|
||||
|
||||
def setupPermissionsDatabase(self, profileDir, permissions):
|
||||
# Open database and create table
|
||||
permDB = sqlite3.connect(os.path.join(profileDir, "permissions.sqlite"))
|
||||
cursor = permDB.cursor();
|
||||
cursor.execute("""CREATE TABLE moz_hosts (
|
||||
id INTEGER PRIMARY KEY,
|
||||
host TEXT,
|
||||
type TEXT,
|
||||
permission INTEGER,
|
||||
expireType INTEGER,
|
||||
expireTime INTEGER)""")
|
||||
|
||||
# Insert desired permissions
|
||||
c = 0
|
||||
for perm in permissions.keys():
|
||||
for host in permissions[perm]:
|
||||
c += 1
|
||||
cursor.execute("INSERT INTO moz_hosts values(?, ?, ?, 1, 0, 0)",
|
||||
(c, host, perm))
|
||||
|
||||
# Commit and close
|
||||
permDB.commit()
|
||||
cursor.close()
|
||||
|
||||
def initializeProfile(self, profileDir, extraPrefs = [], useServerLocations = False):
|
||||
" Sets up the standard testing profile."
|
||||
|
||||
|
@ -297,6 +322,11 @@ class Automation(object):
|
|||
shutil.rmtree(profileDir, True)
|
||||
os.mkdir(profileDir)
|
||||
|
||||
# Set up permissions database
|
||||
locations = self.readLocations()
|
||||
self.setupPermissionsDatabase(profileDir,
|
||||
{'allowXULXBL':map(lambda l: l.host, locations)});
|
||||
|
||||
part = """\
|
||||
user_pref("browser.dom.window.dump.enabled", true);
|
||||
user_pref("dom.allow_scripts_to_close_windows", true);
|
||||
|
@ -354,8 +384,6 @@ user_pref("capability.principal.codebase.p1.subjectName", "");
|
|||
""" % { "origin": "http://" + self.webServer + ":" + str(self.httpPort) }
|
||||
prefs.append(part)
|
||||
else:
|
||||
locations = self.readLocations()
|
||||
|
||||
# Grant God-power to all the privileged servers on which tests run.
|
||||
privileged = filter(lambda loc: "privileged" in loc.options, locations)
|
||||
for (i, l) in itertools.izip(itertools.count(1), privileged):
|
||||
|
|
16
configure.in
16
configure.in
|
@ -118,7 +118,7 @@ dnl ========================================================
|
|||
GLIB_VERSION=1.2.0
|
||||
LIBIDL_VERSION=0.6.3
|
||||
PERL_VERSION=5.006
|
||||
PYTHON_VERSION=2.4
|
||||
PYTHON_VERSION=2.5
|
||||
CAIRO_VERSION=1.8.8
|
||||
PANGO_VERSION=1.14.0
|
||||
GTK2_VERSION=2.10.0
|
||||
|
@ -1088,10 +1088,20 @@ case "$target" in
|
|||
dnl Use the specified value
|
||||
export MACOSX_DEPLOYMENT_TARGET=$_MACOSX_DEPLOYMENT_TARGET
|
||||
AC_DEFINE_UNQUOTED(__ENVIRONMENT_MAC_OS_X_VERION_MIN_REQUIRED__,$_MACOSX_DEPLOYMENT_TARGET)
|
||||
elif test -z "$MACOSX_DEPLOYMENT_TARGET" ; then
|
||||
else
|
||||
dnl No value specified on the command line or in the environment,
|
||||
dnl use architecture minimum.
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.5
|
||||
case "${target_cpu}" in
|
||||
ppc*)
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.5
|
||||
;;
|
||||
i*86)
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.5
|
||||
;;
|
||||
x86_64)
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.6
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -385,6 +385,7 @@ public:
|
|||
static const nsDependentSubstring TrimCharsInSet(const char* aSet,
|
||||
const nsAString& aValue);
|
||||
|
||||
template<PRBool IsWhitespace(PRUnichar)>
|
||||
static const nsDependentSubstring TrimWhitespace(const nsAString& aStr,
|
||||
PRBool aTrimTrailing = PR_TRUE);
|
||||
|
||||
|
|
|
@ -134,9 +134,9 @@ interface nsIDOMParserJS : nsISupports
|
|||
/**
|
||||
* Just like nsIDOMParser.init, but callable from JS.
|
||||
*/
|
||||
void init(in nsIPrincipal principal,
|
||||
in nsIURI documentURI,
|
||||
in nsIURI baseURI);
|
||||
void init([optional] in nsIPrincipal principal,
|
||||
[optional] in nsIURI documentURI,
|
||||
[optional] in nsIURI baseURI);
|
||||
};
|
||||
|
||||
%{ C++
|
||||
|
|
|
@ -1812,7 +1812,6 @@ nsIAtom** const kDefaultAllowedAttributes [] = {
|
|||
&nsGkAtoms::alt,
|
||||
&nsGkAtoms::autocomplete,
|
||||
#ifdef MOZ_MEDIA
|
||||
&nsGkAtoms::autobuffer,
|
||||
&nsGkAtoms::autoplay,
|
||||
#endif
|
||||
&nsGkAtoms::axis,
|
||||
|
@ -1872,6 +1871,7 @@ nsIAtom** const kDefaultAllowedAttributes [] = {
|
|||
&nsGkAtoms::pointSize,
|
||||
#ifdef MOZ_MEDIA
|
||||
&nsGkAtoms::poster,
|
||||
&nsGkAtoms::preload,
|
||||
#endif
|
||||
&nsGkAtoms::prompt,
|
||||
&nsGkAtoms::readonly,
|
||||
|
|
|
@ -561,6 +561,7 @@ nsContentUtils::InitializeEventTable() {
|
|||
{ nsGkAtoms::onreset, NS_FORM_RESET, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onchange, NS_FORM_CHANGE, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onselect, NS_FORM_SELECTED, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::oninvalid, NS_FORM_INVALID, EventNameType_HTMLXUL, NS_EVENT },
|
||||
{ nsGkAtoms::onload, NS_LOAD, EventNameType_All, NS_EVENT },
|
||||
{ nsGkAtoms::onpopstate, NS_POPSTATE, EventNameType_HTMLXUL, NS_EVENT_NULL },
|
||||
{ nsGkAtoms::onunload, NS_PAGE_UNLOAD,
|
||||
|
@ -1912,6 +1913,7 @@ nsContentUtils::TrimCharsInSet(const char* aSet,
|
|||
*/
|
||||
|
||||
// static
|
||||
template<PRBool IsWhitespace(PRUnichar)>
|
||||
const nsDependentSubstring
|
||||
nsContentUtils::TrimWhitespace(const nsAString& aStr, PRBool aTrimTrailing)
|
||||
{
|
||||
|
@ -1921,7 +1923,7 @@ nsContentUtils::TrimWhitespace(const nsAString& aStr, PRBool aTrimTrailing)
|
|||
aStr.EndReading(end);
|
||||
|
||||
// Skip whitespace characters in the beginning
|
||||
while (start != end && nsCRT::IsAsciiSpace(*start)) {
|
||||
while (start != end && IsWhitespace(*start)) {
|
||||
++start;
|
||||
}
|
||||
|
||||
|
@ -1930,7 +1932,7 @@ nsContentUtils::TrimWhitespace(const nsAString& aStr, PRBool aTrimTrailing)
|
|||
while (end != start) {
|
||||
--end;
|
||||
|
||||
if (!nsCRT::IsAsciiSpace(*end)) {
|
||||
if (!IsWhitespace(*end)) {
|
||||
// Step back to the last non-whitespace character.
|
||||
++end;
|
||||
|
||||
|
@ -1945,6 +1947,16 @@ nsContentUtils::TrimWhitespace(const nsAString& aStr, PRBool aTrimTrailing)
|
|||
return Substring(start, end);
|
||||
}
|
||||
|
||||
// Declaring the templates we are going to use avoid linking issues without
|
||||
// inlining the method. Considering there is not so much spaces checking
|
||||
// methods we can consider this to be better than inlining.
|
||||
template
|
||||
const nsDependentSubstring
|
||||
nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(const nsAString&, PRBool);
|
||||
template
|
||||
const nsDependentSubstring
|
||||
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(const nsAString&, PRBool);
|
||||
|
||||
static inline void KeyAppendSep(nsACString& aKey)
|
||||
{
|
||||
if (!aKey.IsEmpty()) {
|
||||
|
@ -5393,7 +5405,7 @@ nsContentUtils::CanAccessNativeAnon()
|
|||
// Some code is running, we can't make the assumption, as above, but we
|
||||
// can't use a native frame, so clear fp.
|
||||
fp = nsnull;
|
||||
} else if (!fp->script) {
|
||||
} else if (!fp->hasScript()) {
|
||||
fp = nsnull;
|
||||
}
|
||||
|
||||
|
@ -5408,8 +5420,8 @@ nsContentUtils::CanAccessNativeAnon()
|
|||
// if they've been cloned into less privileged contexts.
|
||||
static const char prefix[] = "chrome://global/";
|
||||
const char *filename;
|
||||
if (fp && fp->script &&
|
||||
(filename = fp->script->filename) &&
|
||||
if (fp && fp->hasScript() &&
|
||||
(filename = fp->getScript()->filename) &&
|
||||
!strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -335,33 +335,40 @@ nsDOMParser::Init(nsIPrincipal* principal, nsIURI* documentURI,
|
|||
NS_ENSURE_ARG(principal || documentURI);
|
||||
|
||||
mDocumentURI = documentURI;
|
||||
|
||||
if (!mDocumentURI) {
|
||||
principal->GetURI(getter_AddRefs(mDocumentURI));
|
||||
if (!mDocumentURI) {
|
||||
// If we have the system principal, then we'll just use the null principals
|
||||
// uri.
|
||||
if (!mDocumentURI && !nsContentUtils::IsSystemPrincipal(principal)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
mScriptHandlingObject = do_GetWeakReference(aScriptObject);
|
||||
mPrincipal = principal;
|
||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||
NS_ENSURE_TRUE(secMan, NS_ERROR_NOT_AVAILABLE);
|
||||
nsresult rv;
|
||||
if (!mPrincipal) {
|
||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||
NS_ENSURE_TRUE(secMan, NS_ERROR_NOT_AVAILABLE);
|
||||
rv =
|
||||
secMan->GetCodebasePrincipal(mDocumentURI, getter_AddRefs(mPrincipal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mOriginalPrincipal = mPrincipal;
|
||||
} else {
|
||||
mOriginalPrincipal = principal;
|
||||
PRBool isSystem;
|
||||
rv = secMan->IsSystemPrincipal(mPrincipal, &isSystem);
|
||||
if (NS_FAILED(rv) || isSystem) {
|
||||
mOriginalPrincipal = mPrincipal;
|
||||
if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
|
||||
// Don't give DOMParsers the system principal. Use a null
|
||||
// principal instead.
|
||||
mPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!mDocumentURI) {
|
||||
rv = mPrincipal->GetURI(getter_AddRefs(mDocumentURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mBaseURI = baseURI;
|
||||
// Note: if mBaseURI is null, fine. Leave it like that; that will use the
|
||||
|
@ -507,7 +514,8 @@ nsDOMParser::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMParser::Init(nsIPrincipal *principal, nsIURI *documentURI, nsIURI *baseURI)
|
||||
nsDOMParser::Init(nsIPrincipal *aPrincipal, nsIURI *aDocumentURI,
|
||||
nsIURI *aBaseURI)
|
||||
{
|
||||
AttemptedInitMarker marker(&mAttemptedInit);
|
||||
|
||||
|
@ -515,6 +523,19 @@ nsDOMParser::Init(nsIPrincipal *principal, nsIURI *documentURI, nsIURI *baseURI)
|
|||
NS_ENSURE_TRUE(cx, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsIScriptContext* scriptContext = GetScriptContextFromJSContext(cx);
|
||||
return Init(principal, documentURI, baseURI,
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = aPrincipal;
|
||||
|
||||
if (!principal && !aDocumentURI) {
|
||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||
NS_ENSURE_TRUE(secMan, NS_ERROR_UNEXPECTED);
|
||||
|
||||
secMan->GetSubjectPrincipal(getter_AddRefs(principal));
|
||||
|
||||
// We're called from JS; there better be a subject principal, really.
|
||||
NS_ENSURE_TRUE(principal, NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
return Init(principal, aDocumentURI, aBaseURI,
|
||||
scriptContext ? scriptContext->GetGlobalObject() : nsnull);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "nsContentUtils.h"
|
||||
|
||||
nsFormData::nsFormData()
|
||||
: nsFormSubmission(NS_LITERAL_CSTRING("UTF-8"))
|
||||
: nsFormSubmission(NS_LITERAL_CSTRING("UTF-8"), nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ NS_IMETHODIMP
|
|||
nsFormData::GetSendInfo(nsIInputStream** aBody, nsACString& aContentType,
|
||||
nsACString& aCharset)
|
||||
{
|
||||
nsFSMultipartFormData fs(NS_LITERAL_CSTRING("UTF-8"));
|
||||
nsFSMultipartFormData fs(NS_LITERAL_CSTRING("UTF-8"), nsnull);
|
||||
|
||||
for (PRUint32 i = 0; i < mFormData.Length(); ++i) {
|
||||
if (mFormData[i].valueIsFile) {
|
||||
|
|
|
@ -120,9 +120,6 @@ GK_ATOM(attribute, "attribute")
|
|||
GK_ATOM(attributeSet, "attribute-set")
|
||||
GK_ATOM(aural, "aural")
|
||||
GK_ATOM(_auto, "auto")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(autobuffer, "autobuffer")
|
||||
#endif
|
||||
GK_ATOM(autocheck, "autocheck")
|
||||
GK_ATOM(autocomplete, "autocomplete")
|
||||
GK_ATOM(autofocus, "autofocus")
|
||||
|
@ -390,8 +387,12 @@ GK_ATOM(footer, "footer")
|
|||
GK_ATOM(_for, "for")
|
||||
GK_ATOM(forEach, "for-each")
|
||||
GK_ATOM(form, "form")
|
||||
GK_ATOM(formaction, "formaction")
|
||||
GK_ATOM(format, "format")
|
||||
GK_ATOM(formatNumber, "format-number")
|
||||
GK_ATOM(formenctype, "formenctype")
|
||||
GK_ATOM(formmethod, "formmethod")
|
||||
GK_ATOM(formtarget, "formtarget")
|
||||
GK_ATOM(frame, "frame")
|
||||
GK_ATOM(frameborder, "frameborder")
|
||||
GK_ATOM(frameset, "frameset")
|
||||
|
@ -654,6 +655,7 @@ GK_ATOM(onfocus, "onfocus")
|
|||
GK_ATOM(onget, "onget")
|
||||
GK_ATOM(onhashchange, "onhashchange")
|
||||
GK_ATOM(oninput, "oninput")
|
||||
GK_ATOM(oninvalid, "oninvalid")
|
||||
GK_ATOM(onkeydown, "onkeydown")
|
||||
GK_ATOM(onkeypress, "onkeypress")
|
||||
GK_ATOM(onkeyup, "onkeyup")
|
||||
|
@ -724,6 +726,7 @@ GK_ATOM(param, "param")
|
|||
GK_ATOM(parameter, "parameter")
|
||||
GK_ATOM(parent, "parent")
|
||||
GK_ATOM(parsetype, "parsetype")
|
||||
GK_ATOM(pattern, "pattern")
|
||||
GK_ATOM(patternSeparator, "pattern-separator")
|
||||
GK_ATOM(perMille, "per-mille")
|
||||
GK_ATOM(percent, "percent")
|
||||
|
@ -763,6 +766,9 @@ GK_ATOM(preceding, "preceding")
|
|||
GK_ATOM(precedingSibling, "preceding-sibling")
|
||||
GK_ATOM(predicate, "predicate")
|
||||
GK_ATOM(prefix, "prefix")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(preload, "preload")
|
||||
#endif
|
||||
GK_ATOM(preserve, "preserve")
|
||||
GK_ATOM(preserveSpace, "preserve-space")
|
||||
GK_ATOM(preventdefault, "preventdefault")
|
||||
|
@ -797,6 +803,7 @@ GK_ATOM(removeelement, "removeelement")
|
|||
GK_ATOM(renderingobserverlist, "renderingobserverlist")
|
||||
GK_ATOM(repeat, "repeat")
|
||||
GK_ATOM(replace, "replace")
|
||||
GK_ATOM(required, "required")
|
||||
GK_ATOM(reset, "reset")
|
||||
GK_ATOM(resizeafter, "resizeafter")
|
||||
GK_ATOM(resizebefore, "resizebefore")
|
||||
|
@ -1209,7 +1216,6 @@ GK_ATOM(over, "over")
|
|||
GK_ATOM(pad, "pad")
|
||||
GK_ATOM(path, "path")
|
||||
GK_ATOM(pathLength, "pathLength")
|
||||
GK_ATOM(pattern, "pattern")
|
||||
GK_ATOM(patternContentUnits, "patternContentUnits")
|
||||
GK_ATOM(patternTransform, "patternTransform")
|
||||
GK_ATOM(patternUnits, "patternUnits")
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
#include "prlog.h"
|
||||
#include "nsIChannelPolicy.h"
|
||||
#include "nsChannelPolicy.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
|
||||
|
@ -189,13 +190,15 @@ IsScriptEventHandler(nsIScriptElement *aScriptElement)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
const nsAString& for_str = nsContentUtils::TrimWhitespace(forAttr);
|
||||
const nsAString& for_str =
|
||||
nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(forAttr);
|
||||
if (!for_str.LowerCaseEqualsLiteral("window")) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// We found for="window", now check for event="onload".
|
||||
const nsAString& event_str = nsContentUtils::TrimWhitespace(eventAttr, PR_FALSE);
|
||||
const nsAString& event_str =
|
||||
nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(eventAttr, PR_FALSE);
|
||||
if (!StringBeginsWith(event_str, NS_LITERAL_STRING("onload"),
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
// It ain't "onload.*".
|
||||
|
|
|
@ -16,6 +16,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=564863
|
|||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<style>
|
||||
* {
|
||||
color: rgb(0, 0, 0);
|
||||
}
|
||||
#div_id {
|
||||
color: rgb(10, 10, 10);
|
||||
}
|
||||
|
|
|
@ -92,8 +92,7 @@ WebGLContext::WebGLContext()
|
|||
mPixelStoreFlipY = PR_FALSE;
|
||||
mPixelStorePremultiplyAlpha = PR_FALSE;
|
||||
|
||||
// eventually true
|
||||
mShaderValidation = PR_FALSE;
|
||||
mShaderValidation = PR_TRUE;
|
||||
|
||||
mMapBuffers.Init();
|
||||
mMapTextures.Init();
|
||||
|
|
|
@ -447,26 +447,21 @@ WebGLContext::InitAndValidateGL()
|
|||
gl->fEnable(LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
}
|
||||
|
||||
static bool didTranslatorCheck = false;
|
||||
if (!didTranslatorCheck) {
|
||||
// Check the shader validator pref
|
||||
nsCOMPtr<nsIPrefBranch> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(prefService != nsnull, NS_ERROR_FAILURE);
|
||||
// Check the shader validator pref
|
||||
nsCOMPtr<nsIPrefBranch> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(prefService != nsnull, NS_ERROR_FAILURE);
|
||||
|
||||
prefService->GetBoolPref("webgl.shader_validator", &mShaderValidation);
|
||||
prefService->GetBoolPref("webgl.shader_validator", &mShaderValidation);
|
||||
|
||||
#if defined(USE_ANGLE)
|
||||
// initialize shader translator
|
||||
if (mShaderValidation) {
|
||||
if (!ShInitialize()) {
|
||||
LogMessage("GLSL translator initialization failed!");
|
||||
return PR_FALSE;
|
||||
}
|
||||
// initialize shader translator
|
||||
if (mShaderValidation) {
|
||||
if (!ShInitialize()) {
|
||||
LogMessage("GLSL translator initialization failed!");
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
didTranslatorCheck = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -2327,8 +2327,7 @@ nsCanvasRenderingContext2D::SetFont(const nsAString& font)
|
|||
// We know the declaration is not !important, so we can use
|
||||
// GetNormalBlock().
|
||||
const nsCSSValue *fsaVal =
|
||||
declaration->GetNormalBlock()->
|
||||
ValueStorageFor(eCSSProperty_font_size_adjust);
|
||||
declaration->GetNormalBlock()->ValueFor(eCSSProperty_font_size_adjust);
|
||||
if (!fsaVal || (fsaVal->GetUnit() != eCSSUnit_None &&
|
||||
fsaVal->GetUnit() != eCSSUnit_System_Font)) {
|
||||
// We got an all-property value or a syntax error. The spec says
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "nsIScriptableRegion.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_2(nsDOMDataTransfer, mDragTarget, mDragImage)
|
||||
|
||||
|
@ -336,7 +337,7 @@ nsDOMDataTransfer::GetData(const nsAString& aFormat, nsAString& aData)
|
|||
aData.Assign(Substring(stringdata, lastidx));
|
||||
else
|
||||
aData.Assign(Substring(stringdata, lastidx, idx - lastidx));
|
||||
aData = nsContentUtils::TrimWhitespace(aData, PR_TRUE);
|
||||
aData = nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(aData, PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
lastidx = idx + 1;
|
||||
|
|
|
@ -65,7 +65,7 @@ static const char* const sEventNames[] = {
|
|||
"mouseout", "MozMouseHittest", "mousemove", "contextmenu", "keydown", "keyup", "keypress",
|
||||
"focus", "blur", "load", "popstate", "beforeunload", "unload",
|
||||
"hashchange", "readystatechange", "abort", "error",
|
||||
"submit", "reset", "change", "select", "input", "text",
|
||||
"submit", "reset", "change", "select", "input", "invalid", "text",
|
||||
"compositionstart", "compositionend", "popupshowing", "popupshown",
|
||||
"popuphiding", "popuphidden", "close", "command", "broadcast", "commandupdate",
|
||||
"dragenter", "dragover", "dragexit", "dragdrop", "draggesture",
|
||||
|
@ -1149,6 +1149,8 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
|||
return sEventNames[eDOMEvents_select];
|
||||
case NS_FORM_INPUT:
|
||||
return sEventNames[eDOMEvents_input];
|
||||
case NS_FORM_INVALID:
|
||||
return sEventNames[eDOMEvents_invalid];
|
||||
case NS_RESIZE_EVENT:
|
||||
return sEventNames[eDOMEvents_resize];
|
||||
case NS_SCROLL_EVENT:
|
||||
|
|
|
@ -88,6 +88,7 @@ public:
|
|||
eDOMEvents_change,
|
||||
eDOMEvents_select,
|
||||
eDOMEvents_input,
|
||||
eDOMEvents_invalid,
|
||||
eDOMEvents_text,
|
||||
eDOMEvents_compositionstart,
|
||||
eDOMEvents_compositionend,
|
||||
|
|
|
@ -1790,8 +1790,10 @@ nsEventStateManager::FireContextClick()
|
|||
PRInt32 type = formCtrl->GetType();
|
||||
|
||||
allowedToDispatch = (type == NS_FORM_INPUT_TEXT ||
|
||||
type == NS_FORM_INPUT_EMAIL ||
|
||||
type == NS_FORM_INPUT_SEARCH ||
|
||||
type == NS_FORM_INPUT_TEL ||
|
||||
type == NS_FORM_INPUT_URL ||
|
||||
type == NS_FORM_INPUT_PASSWORD ||
|
||||
type == NS_FORM_INPUT_FILE ||
|
||||
type == NS_FORM_TEXTAREA);
|
||||
|
@ -3292,7 +3294,6 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
|
||||
//Reset target frame to null to avoid mistargeting after reentrant event
|
||||
mCurrentTarget = nsnull;
|
||||
mCurrentTargetContent = nsnull;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -3612,7 +3613,6 @@ nsEventStateManager::DispatchMouseEvent(nsGUIEvent* aEvent, PRUint32 aMessage,
|
|||
event.inputSource = static_cast<nsMouseEvent*>(aEvent)->inputSource;
|
||||
|
||||
mCurrentTargetContent = aTargetContent;
|
||||
mCurrentTarget = nsnull;
|
||||
|
||||
nsIFrame* targetFrame = nsnull;
|
||||
if (aTargetContent) {
|
||||
|
@ -3629,7 +3629,6 @@ nsEventStateManager::DispatchMouseEvent(nsGUIEvent* aEvent, PRUint32 aMessage,
|
|||
}
|
||||
|
||||
mCurrentTargetContent = nsnull;
|
||||
mCurrentTarget = nsnull;
|
||||
|
||||
return targetFrame;
|
||||
}
|
||||
|
@ -3794,7 +3793,6 @@ nsEventStateManager::GenerateMouseEnterExit(nsGUIEvent* aEvent)
|
|||
|
||||
// reset mCurretTargetContent to what it was
|
||||
mCurrentTargetContent = targetBeforeEvent;
|
||||
mCurrentTarget = nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -122,26 +122,37 @@ public:
|
|||
aCharset = mCharset;
|
||||
}
|
||||
|
||||
nsIContent* GetOriginatingElement() const
|
||||
{
|
||||
return mOriginatingElement.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Can only be constructed by subclasses.
|
||||
*
|
||||
* @param aCharset the charset of the form as a string
|
||||
* @param aOriginatingElement the originating element (can be null)
|
||||
*/
|
||||
nsFormSubmission(const nsACString& aCharset)
|
||||
nsFormSubmission(const nsACString& aCharset, nsIContent* aOriginatingElement)
|
||||
: mCharset(aCharset)
|
||||
, mOriginatingElement(aOriginatingElement)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsFormSubmission);
|
||||
}
|
||||
|
||||
// The name of the encoder charset
|
||||
nsCString mCharset;
|
||||
|
||||
// Originating element.
|
||||
nsCOMPtr<nsIContent> mOriginatingElement;
|
||||
};
|
||||
|
||||
class nsEncodingFormSubmission : public nsFormSubmission
|
||||
{
|
||||
public:
|
||||
nsEncodingFormSubmission(const nsACString& aCharset);
|
||||
nsEncodingFormSubmission(const nsACString& aCharset,
|
||||
nsIContent* aOriginatingElement);
|
||||
|
||||
virtual ~nsEncodingFormSubmission();
|
||||
|
||||
|
@ -169,7 +180,8 @@ public:
|
|||
/**
|
||||
* @param aCharset the charset of the form as a string
|
||||
*/
|
||||
nsFSMultipartFormData(const nsACString& aCharset);
|
||||
nsFSMultipartFormData(const nsACString& aCharset,
|
||||
nsIContent* aOriginatingElement);
|
||||
~nsFSMultipartFormData();
|
||||
|
||||
virtual nsresult AddNameValuePair(const nsAString& aName,
|
||||
|
@ -223,9 +235,11 @@ private:
|
|||
* Get a submission object based on attributes in the form (ENCTYPE and METHOD)
|
||||
*
|
||||
* @param aForm the form to get a submission object based on
|
||||
* @param aOriginatingElement the originating element (can be null)
|
||||
* @param aFormSubmission the form submission object (out param)
|
||||
*/
|
||||
nsresult GetSubmissionFromForm(nsGenericHTMLElement* aForm,
|
||||
nsGenericHTMLElement* aOriginatingElement,
|
||||
nsFormSubmission** aFormSubmission);
|
||||
|
||||
#endif /* nsIFormSubmission_h___ */
|
||||
|
|
|
@ -430,6 +430,51 @@ protected:
|
|||
* Called asynchronously to release a self-reference to this element.
|
||||
*/
|
||||
void DoRemoveSelfReference();
|
||||
|
||||
/**
|
||||
* Possible values of the 'preload' attribute.
|
||||
*/
|
||||
enum PreloadAttrValue {
|
||||
PRELOAD_ATTR_EMPTY, // set to ""
|
||||
PRELOAD_ATTR_NONE, // set to "none"
|
||||
PRELOAD_ATTR_METADATA, // set to "metadata"
|
||||
PRELOAD_ATTR_AUTO // set to "auto"
|
||||
};
|
||||
|
||||
/**
|
||||
* The preloading action to perform. These dictate how we react to the
|
||||
* preload attribute. See mPreloadAction.
|
||||
*/
|
||||
enum PreloadAction {
|
||||
PRELOAD_UNDEFINED = 0, // not determined - used only for initialization
|
||||
PRELOAD_NONE = 1, // do not preload
|
||||
PRELOAD_METADATA = 2, // preload only the metadata (and first frame)
|
||||
PRELOAD_ENOUGH = 3 // preload enough data to allow uninterrupted
|
||||
// playback
|
||||
};
|
||||
|
||||
/**
|
||||
* Suspends the load of resource at aURI, so that it can be resumed later
|
||||
* by ResumeLoad(). This is called when we have a media with a 'preload'
|
||||
* attribute value of 'none', during the resource selection algorithm.
|
||||
*/
|
||||
void SuspendLoad(nsIURI* aURI);
|
||||
|
||||
/**
|
||||
* Resumes a previously suspended load (suspended by SuspendLoad(uri)).
|
||||
* Will continue running the resource selection algorithm.
|
||||
* Sets mPreloadAction to aAction.
|
||||
*/
|
||||
void ResumeLoad(PreloadAction aAction);
|
||||
|
||||
/**
|
||||
* Handle a change to the preload attribute. Should be called whenever the
|
||||
* value (or presence) of the preload attribute changes. The change in
|
||||
* attribute value may cause a change in the mPreloadAction of this
|
||||
* element. If there is a change then this method will initiate any
|
||||
* behaviour that is necessary to implement the action.
|
||||
*/
|
||||
void UpdatePreloadAction();
|
||||
|
||||
nsRefPtr<nsMediaDecoder> mDecoder;
|
||||
|
||||
|
@ -482,10 +527,23 @@ protected:
|
|||
// Current audio volume
|
||||
float mVolume;
|
||||
|
||||
// If we're loading a preload:none media, we'll record the URI we're
|
||||
// attempting to load in mPreloadURI, and delay loading the resource until
|
||||
// the user initiates a load by either playing the resource, or explicitly
|
||||
// loading it.
|
||||
nsCOMPtr<nsIURI> mPreloadURI;
|
||||
|
||||
// Stores the current preload action for this element. Initially set to
|
||||
// PRELOAD_UNDEFINED, its value is changed by calling
|
||||
// UpdatePreloadAction().
|
||||
PreloadAction mPreloadAction;
|
||||
|
||||
// Size of the media. Updated by the decoder on the main thread if
|
||||
// it changes. Defaults to a width and height of -1 if not set.
|
||||
nsIntSize mMediaSize;
|
||||
|
||||
nsRefPtr<gfxASurface> mPrintSurface;
|
||||
|
||||
// If true then we have begun downloading the media content.
|
||||
// Set to false when completed, or not yet started.
|
||||
PRPackedBool mBegun;
|
||||
|
@ -551,11 +609,13 @@ protected:
|
|||
PRPackedBool mIsRunningSelectResource;
|
||||
|
||||
// PR_TRUE if we suspended the decoder because we were paused,
|
||||
// autobuffer and autoplay were not set, and we loaded the first frame.
|
||||
// preloading metadata is enabled, autoplay was not enabled, and we loaded
|
||||
// the first frame.
|
||||
PRPackedBool mSuspendedAfterFirstFrame;
|
||||
|
||||
// PR_TRUE if we are allowed to suspend the decoder because we were paused,
|
||||
// autobuffer and autoplay were not set, and we loaded the first frame.
|
||||
// preloading metdata was enabled, autoplay was not enabled, and we loaded
|
||||
// the first frame.
|
||||
PRPackedBool mAllowSuspendAfterFirstFrame;
|
||||
|
||||
// PR_TRUE if we've played or completed a seek. We use this to determine
|
||||
|
@ -571,7 +631,11 @@ protected:
|
|||
// down.
|
||||
PRPackedBool mShuttingDown;
|
||||
|
||||
nsRefPtr<gfxASurface> mPrintSurface;
|
||||
// PR_TRUE if we've suspended a load in the resource selection algorithm
|
||||
// due to loading a preload:none media. When PR_TRUE, the resource we'll
|
||||
// load when the user initiates either playback or an explicit load is
|
||||
// stored in mPreloadURI.
|
||||
PRPackedBool mLoadIsSuspended;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -81,6 +81,7 @@ enum ButtonElementTypes {
|
|||
enum InputElementTypes {
|
||||
NS_FORM_INPUT_BUTTON = NS_FORM_INPUT_ELEMENT + 1,
|
||||
NS_FORM_INPUT_CHECKBOX,
|
||||
NS_FORM_INPUT_EMAIL,
|
||||
NS_FORM_INPUT_FILE,
|
||||
NS_FORM_INPUT_HIDDEN,
|
||||
NS_FORM_INPUT_RESET,
|
||||
|
@ -91,6 +92,7 @@ enum InputElementTypes {
|
|||
NS_FORM_INPUT_SUBMIT,
|
||||
NS_FORM_INPUT_TEL,
|
||||
NS_FORM_INPUT_TEXT,
|
||||
NS_FORM_INPUT_URL,
|
||||
eInputElementTypesMax
|
||||
};
|
||||
|
||||
|
@ -99,8 +101,8 @@ PR_STATIC_ASSERT((PRUint32)eButtonElementTypesMax < (PRUint32)NS_FORM_INPUT_ELEM
|
|||
PR_STATIC_ASSERT((PRUint32)eInputElementTypesMax < 1<<8);
|
||||
|
||||
#define NS_IFORMCONTROL_IID \
|
||||
{ 0x0dc5083b, 0xb0a8, 0x48c4, \
|
||||
{ 0xb2, 0xeb, 0xc2, 0x4f, 0xfb, 0x7e, 0xc2, 0x8e } }
|
||||
{ 0xc2f7723a, 0x106a, 0x47ef, \
|
||||
{ 0xa9, 0xff, 0x4b, 0x4f, 0x73, 0x47, 0xe7, 0xa6 } }
|
||||
|
||||
/**
|
||||
* Interface which all form controls (e.g. buttons, checkboxes, text,
|
||||
|
@ -156,11 +158,8 @@ public:
|
|||
* submission object
|
||||
* @param aFormSubmission the form submission to notify of names/values/files
|
||||
* to submit
|
||||
* @param aSubmitElement the element that was pressed to submit (possibly
|
||||
* null)
|
||||
*/
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement) = 0;
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) = 0;
|
||||
|
||||
/**
|
||||
* Save to presentation state. The form control will determine whether it
|
||||
|
|
|
@ -112,6 +112,8 @@ CPPSRCS = \
|
|||
nsHTMLTextAreaElement.cpp \
|
||||
nsHTMLTimeRanges.cpp \
|
||||
nsHTMLTitleElement.cpp \
|
||||
nsDOMValidityState.cpp \
|
||||
nsConstraintValidation.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_MEDIA
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mounir Lamouri <mounir.lamouri@mozilla.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsConstraintValidation.h"
|
||||
|
||||
#include "nsAString.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsHTMLFormElement.h"
|
||||
|
||||
nsConstraintValidation::~nsConstraintValidation()
|
||||
{
|
||||
if (mValidity) {
|
||||
mValidity->Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsConstraintValidation::GetValidity(nsIDOMValidityState** aValidity)
|
||||
{
|
||||
if (!mValidity) {
|
||||
mValidity = new nsDOMValidityState(this);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aValidity = mValidity);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsConstraintValidation::GetWillValidate(PRBool* aWillValidate,
|
||||
nsGenericHTMLFormElement* aElement)
|
||||
{
|
||||
*aWillValidate = IsCandidateForConstraintValidation(aElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsConstraintValidation::GetValidationMessage(nsAString & aValidationMessage,
|
||||
nsGenericHTMLFormElement* aElement)
|
||||
{
|
||||
aValidationMessage.Truncate();
|
||||
|
||||
if (IsCandidateForConstraintValidation(aElement) && !IsValid()) {
|
||||
if (!mCustomValidity.IsEmpty()) {
|
||||
aValidationMessage.Assign(mCustomValidity);
|
||||
} else if (IsTooLong()) {
|
||||
GetValidationMessage(aValidationMessage, VALIDATION_MESSAGE_TOO_LONG);
|
||||
} else if (IsValueMissing()) {
|
||||
GetValidationMessage(aValidationMessage, VALIDATION_MESSAGE_VALUE_MISSING);
|
||||
} else if (HasTypeMismatch()) {
|
||||
GetValidationMessage(aValidationMessage, VALIDATION_MESSAGE_TYPE_MISMATCH);
|
||||
} else if (HasPatternMismatch()) {
|
||||
GetValidationMessage(aValidationMessage, VALIDATION_MESSAGE_PATTERN_MISMATCH);
|
||||
} else {
|
||||
// TODO: The other messages have not been written
|
||||
// because related constraint validation are not implemented yet.
|
||||
// We should not be here.
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
} else {
|
||||
aValidationMessage.Truncate();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsConstraintValidation::CheckValidity(PRBool* aValidity,
|
||||
nsGenericHTMLFormElement* aElement)
|
||||
{
|
||||
if (!IsCandidateForConstraintValidation(aElement) || IsValid()) {
|
||||
*aValidity = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aValidity = PR_FALSE;
|
||||
|
||||
return nsContentUtils::DispatchTrustedEvent(aElement->GetOwnerDoc(),
|
||||
static_cast<nsIContent*>(aElement),
|
||||
NS_LITERAL_STRING("invalid"),
|
||||
PR_FALSE, PR_TRUE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsConstraintValidation::SetCustomValidity(const nsAString & aError)
|
||||
{
|
||||
mCustomValidity.Assign(aError);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsConstraintValidation::HasCustomError() const
|
||||
{
|
||||
return !mCustomValidity.IsEmpty();
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsConstraintValidation::IsValid()
|
||||
{
|
||||
return !(IsValueMissing() || HasTypeMismatch() || HasPatternMismatch() ||
|
||||
IsTooLong() || HasRangeUnderflow() || HasRangeOverflow() ||
|
||||
HasStepMismatch() || HasCustomError());
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsConstraintValidation::IsCandidateForConstraintValidation(nsGenericHTMLFormElement* aElement)
|
||||
{
|
||||
/**
|
||||
* An element is never candidate for constraint validation if:
|
||||
* - it is disabled ;
|
||||
* - TODO: or it's ancestor is a datalist element (bug 555840).
|
||||
* We are doing these checks here to prevent writing them in every
|
||||
* |IsBarredFromConstraintValidation| function.
|
||||
*/
|
||||
|
||||
// At the moment, every elements which can be candidate for constraint
|
||||
// validation can be disabled. However, using |CanBeDisabled| is future-proof.
|
||||
if (aElement->CanBeDisabled() &&
|
||||
aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return !IsBarredFromConstraintValidation();
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mounir Lamouri <mounir.lamouri@mozilla.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsConstraintValidition_h___
|
||||
#define nsConstraintValidition_h___
|
||||
|
||||
#include "nsDOMValidityState.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsGenericHTMLFormElement;
|
||||
|
||||
/**
|
||||
* This interface is used for form elements implementing the
|
||||
* validity constraint API.
|
||||
* See: http://dev.w3.org/html5/spec/forms.html#the-constraint-validation-api
|
||||
*/
|
||||
class nsConstraintValidation
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~nsConstraintValidation();
|
||||
|
||||
nsresult GetValidity(nsIDOMValidityState** aValidity);
|
||||
nsresult GetWillValidate(PRBool* aWillValidate,
|
||||
nsGenericHTMLFormElement* aElement);
|
||||
nsresult GetValidationMessage(nsAString & aValidationMessage,
|
||||
nsGenericHTMLFormElement* aElement);
|
||||
nsresult CheckValidity(PRBool* aValidity,
|
||||
nsGenericHTMLFormElement* aElement);
|
||||
nsresult SetCustomValidity(const nsAString & aError);
|
||||
|
||||
virtual PRBool IsValueMissing () { return PR_FALSE; }
|
||||
virtual PRBool HasTypeMismatch () { return PR_FALSE; }
|
||||
virtual PRBool HasPatternMismatch() { return PR_FALSE; }
|
||||
virtual PRBool IsTooLong () { return PR_FALSE; }
|
||||
virtual PRBool HasRangeUnderflow () { return PR_FALSE; }
|
||||
virtual PRBool HasRangeOverflow () { return PR_FALSE; }
|
||||
virtual PRBool HasStepMismatch () { return PR_FALSE; }
|
||||
PRBool HasCustomError () const;
|
||||
PRBool IsValid ();
|
||||
|
||||
protected:
|
||||
|
||||
enum ValidationMessageType
|
||||
{
|
||||
VALIDATION_MESSAGE_VALUE_MISSING,
|
||||
VALIDATION_MESSAGE_TYPE_MISMATCH,
|
||||
VALIDATION_MESSAGE_PATTERN_MISMATCH,
|
||||
VALIDATION_MESSAGE_TOO_LONG,
|
||||
VALIDATION_MESSAGE_RANGE_UNDERFLOW,
|
||||
VALIDATION_MESSAGE_RANGE_OVERFLOW,
|
||||
VALIDATION_MESSAGE_STEP_MISMATCH
|
||||
};
|
||||
|
||||
PRBool IsCandidateForConstraintValidation(nsGenericHTMLFormElement* aElement);
|
||||
virtual PRBool IsBarredFromConstraintValidation() { return PR_FALSE; }
|
||||
virtual nsresult GetValidationMessage(nsAString& aValidationMessage,
|
||||
ValidationMessageType aType) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsDOMValidityState> mValidity;
|
||||
nsString mCustomValidity;
|
||||
};
|
||||
|
||||
/**
|
||||
* Use this macro for class inherit from nsConstraintValidation to forward
|
||||
* functions to nsConstraintValidation.
|
||||
*/
|
||||
#define NS_FORWARD_NSCONSTRAINTVALIDATION \
|
||||
NS_IMETHOD GetValidity(nsIDOMValidityState** aValidity) { \
|
||||
return nsConstraintValidation::GetValidity(aValidity); \
|
||||
} \
|
||||
NS_IMETHOD GetWillValidate(PRBool* aWillValidate) { \
|
||||
return nsConstraintValidation::GetWillValidate(aWillValidate, this); \
|
||||
} \
|
||||
NS_IMETHOD GetValidationMessage(nsAString& aValidationMessage) { \
|
||||
return nsConstraintValidation::GetValidationMessage(aValidationMessage, this); \
|
||||
} \
|
||||
NS_IMETHOD SetCustomValidity(const nsAString& aError) { \
|
||||
return nsConstraintValidation::SetCustomValidity(aError); \
|
||||
} \
|
||||
NS_IMETHOD CheckValidity(PRBool* aValidity) { \
|
||||
return nsConstraintValidation::CheckValidity(aValidity, this); \
|
||||
}
|
||||
|
||||
|
||||
/* Use this macro when class declares functions from nsConstraintValidation */
|
||||
#define NS_IMPL_NSCONSTRAINTVALIDATION(_from) \
|
||||
NS_IMETHODIMP _from::GetValidity(nsIDOMValidityState** aValidity) { \
|
||||
return nsConstraintValidation::GetValidity(aValidity); \
|
||||
} \
|
||||
NS_IMETHODIMP _from::GetWillValidate(PRBool* aWillValidate) { \
|
||||
return nsConstraintValidation::GetWillValidate(aWillValidate, this); \
|
||||
} \
|
||||
NS_IMETHODIMP _from::GetValidationMessage(nsAString& aValidationMessage) { \
|
||||
return nsConstraintValidation::GetValidationMessage(aValidationMessage, this); \
|
||||
} \
|
||||
NS_IMETHODIMP _from::SetCustomValidity(const nsAString& aError) { \
|
||||
return nsConstraintValidation::SetCustomValidity(aError); \
|
||||
} \
|
||||
NS_IMETHODIMP _from::CheckValidity(PRBool* aValidity) { \
|
||||
return nsConstraintValidation::CheckValidity(aValidity, this); \
|
||||
}
|
||||
|
||||
|
||||
#endif // nsConstraintValidation_h___
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mounir Lamouri <mounir.lamouri@mozilla.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDOMValidityState.h"
|
||||
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsConstraintValidation.h"
|
||||
|
||||
|
||||
DOMCI_DATA(ValidityState, nsDOMValidityState)
|
||||
|
||||
NS_IMPL_ADDREF(nsDOMValidityState)
|
||||
NS_IMPL_RELEASE(nsDOMValidityState)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMValidityState)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMValidityState)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMValidityState)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ValidityState)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsDOMValidityState::nsDOMValidityState(nsConstraintValidation* aConstraintValidation)
|
||||
: mConstraintValidation(aConstraintValidation)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMValidityState::GetValueMissing(PRBool* aValueMissing)
|
||||
{
|
||||
*aValueMissing = mConstraintValidation && mConstraintValidation->IsValueMissing();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMValidityState::GetTypeMismatch(PRBool* aTypeMismatch)
|
||||
{
|
||||
*aTypeMismatch = mConstraintValidation && mConstraintValidation->HasTypeMismatch();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMValidityState::GetPatternMismatch(PRBool* aPatternMismatch)
|
||||
{
|
||||
*aPatternMismatch = mConstraintValidation && mConstraintValidation->HasPatternMismatch();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMValidityState::GetTooLong(PRBool* aTooLong)
|
||||
{
|
||||
*aTooLong = mConstraintValidation && mConstraintValidation->IsTooLong();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMValidityState::GetRangeUnderflow(PRBool* aRangeUnderflow)
|
||||
{
|
||||
*aRangeUnderflow = mConstraintValidation && mConstraintValidation->HasRangeUnderflow();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMValidityState::GetRangeOverflow(PRBool* aRangeOverflow)
|
||||
{
|
||||
*aRangeOverflow = mConstraintValidation && mConstraintValidation->HasRangeOverflow();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMValidityState::GetStepMismatch(PRBool* aStepMismatch)
|
||||
{
|
||||
*aStepMismatch = mConstraintValidation && mConstraintValidation->HasStepMismatch();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMValidityState::GetCustomError(PRBool* aCustomError)
|
||||
{
|
||||
*aCustomError = mConstraintValidation && mConstraintValidation->HasCustomError();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMValidityState::GetValid(PRBool* aValid)
|
||||
{
|
||||
*aValid = !mConstraintValidation || mConstraintValidation->IsValid();
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mounir Lamouri <mounir.lamouri@mozilla.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsDOMValidityState_h__
|
||||
#define nsDOMValidityState_h__
|
||||
|
||||
#include "nsIDOMValidityState.h"
|
||||
|
||||
class nsConstraintValidation;
|
||||
|
||||
class nsDOMValidityState : public nsIDOMValidityState
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMVALIDITYSTATE
|
||||
|
||||
friend class nsConstraintValidation;
|
||||
|
||||
protected:
|
||||
// This function should be called by nsConstraintValidation
|
||||
// to set mConstraintValidation to null to be sure it will not be called.
|
||||
void Disconnect()
|
||||
{
|
||||
mConstraintValidation = nsnull;
|
||||
}
|
||||
|
||||
nsDOMValidityState(nsConstraintValidation* aConstraintValidation);
|
||||
|
||||
nsConstraintValidation* mConstraintValidation;
|
||||
};
|
||||
|
||||
#endif // nsDOMValidityState_h__
|
||||
|
|
@ -98,8 +98,9 @@ public:
|
|||
*/
|
||||
nsFSURLEncoded(const nsACString& aCharset,
|
||||
PRInt32 aMethod,
|
||||
nsIDocument* aDocument)
|
||||
: nsEncodingFormSubmission(aCharset),
|
||||
nsIDocument* aDocument,
|
||||
nsIContent* aOriginatingElement)
|
||||
: nsEncodingFormSubmission(aCharset, aOriginatingElement),
|
||||
mMethod(aMethod),
|
||||
mDocument(aDocument),
|
||||
mWarnedFileControl(PR_FALSE)
|
||||
|
@ -403,8 +404,9 @@ nsFSURLEncoded::URLEncode(const nsAString& aStr, nsCString& aEncoded)
|
|||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
nsFSMultipartFormData::nsFSMultipartFormData(const nsACString& aCharset)
|
||||
: nsEncodingFormSubmission(aCharset)
|
||||
nsFSMultipartFormData::nsFSMultipartFormData(const nsACString& aCharset,
|
||||
nsIContent* aOriginatingElement)
|
||||
: nsEncodingFormSubmission(aCharset, aOriginatingElement)
|
||||
{
|
||||
mPostDataStream =
|
||||
do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
|
||||
|
@ -595,8 +597,8 @@ nsFSMultipartFormData::AddPostDataStream()
|
|||
class nsFSTextPlain : public nsEncodingFormSubmission
|
||||
{
|
||||
public:
|
||||
nsFSTextPlain(const nsACString& aCharset)
|
||||
: nsEncodingFormSubmission(aCharset)
|
||||
nsFSTextPlain(const nsACString& aCharset, nsIContent* aOriginatingElement)
|
||||
: nsEncodingFormSubmission(aCharset, aOriginatingElement)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -691,8 +693,9 @@ nsFSTextPlain::GetEncodedSubmission(nsIURI* aURI,
|
|||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
nsEncodingFormSubmission::nsEncodingFormSubmission(const nsACString& aCharset)
|
||||
: nsFormSubmission(aCharset)
|
||||
nsEncodingFormSubmission::nsEncodingFormSubmission(const nsACString& aCharset,
|
||||
nsIContent* aOriginatingElement)
|
||||
: nsFormSubmission(aCharset, aOriginatingElement)
|
||||
{
|
||||
nsCAutoString charset(aCharset);
|
||||
// canonical name is passed so that we just have to check against
|
||||
|
@ -800,6 +803,7 @@ GetEnumAttr(nsGenericHTMLElement* aContent,
|
|||
|
||||
nsresult
|
||||
GetSubmissionFromForm(nsGenericHTMLElement* aForm,
|
||||
nsGenericHTMLElement* aOriginatingElement,
|
||||
nsFormSubmission** aFormSubmission)
|
||||
{
|
||||
// Get all the information necessary to encode the form data
|
||||
|
@ -808,11 +812,21 @@ GetSubmissionFromForm(nsGenericHTMLElement* aForm,
|
|||
|
||||
// Get encoding type (default: urlencoded)
|
||||
PRInt32 enctype = NS_FORM_ENCTYPE_URLENCODED;
|
||||
GetEnumAttr(aForm, nsGkAtoms::enctype, &enctype);
|
||||
if (aOriginatingElement &&
|
||||
aOriginatingElement->HasAttr(kNameSpaceID_None, nsGkAtoms::formenctype)) {
|
||||
GetEnumAttr(aOriginatingElement, nsGkAtoms::formenctype, &enctype);
|
||||
} else {
|
||||
GetEnumAttr(aForm, nsGkAtoms::enctype, &enctype);
|
||||
}
|
||||
|
||||
// Get method (default: GET)
|
||||
PRInt32 method = NS_FORM_METHOD_GET;
|
||||
GetEnumAttr(aForm, nsGkAtoms::method, &method);
|
||||
if (aOriginatingElement &&
|
||||
aOriginatingElement->HasAttr(kNameSpaceID_None, nsGkAtoms::formmethod)) {
|
||||
GetEnumAttr(aOriginatingElement, nsGkAtoms::formmethod, &method);
|
||||
} else {
|
||||
GetEnumAttr(aForm, nsGkAtoms::method, &method);
|
||||
}
|
||||
|
||||
// Get charset
|
||||
nsCAutoString charset;
|
||||
|
@ -821,21 +835,29 @@ GetSubmissionFromForm(nsGenericHTMLElement* aForm,
|
|||
// Choose encoder
|
||||
if (method == NS_FORM_METHOD_POST &&
|
||||
enctype == NS_FORM_ENCTYPE_MULTIPART) {
|
||||
*aFormSubmission = new nsFSMultipartFormData(charset);
|
||||
*aFormSubmission = new nsFSMultipartFormData(charset, aOriginatingElement);
|
||||
} else if (method == NS_FORM_METHOD_POST &&
|
||||
enctype == NS_FORM_ENCTYPE_TEXTPLAIN) {
|
||||
*aFormSubmission = new nsFSTextPlain(charset);
|
||||
*aFormSubmission = new nsFSTextPlain(charset, aOriginatingElement);
|
||||
} else {
|
||||
nsIDocument* doc = aForm->GetOwnerDoc();
|
||||
if (enctype == NS_FORM_ENCTYPE_MULTIPART ||
|
||||
enctype == NS_FORM_ENCTYPE_TEXTPLAIN) {
|
||||
nsAutoString enctypeStr;
|
||||
aForm->GetAttr(kNameSpaceID_None, nsGkAtoms::enctype, enctypeStr);
|
||||
if (aOriginatingElement &&
|
||||
aOriginatingElement->HasAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::formenctype)) {
|
||||
aOriginatingElement->GetAttr(kNameSpaceID_None, nsGkAtoms::formenctype,
|
||||
enctypeStr);
|
||||
} else {
|
||||
aForm->GetAttr(kNameSpaceID_None, nsGkAtoms::enctype, enctypeStr);
|
||||
}
|
||||
const PRUnichar* enctypeStrPtr = enctypeStr.get();
|
||||
SendJSWarning(doc, "ForgotPostWarning",
|
||||
&enctypeStrPtr, 1);
|
||||
}
|
||||
*aFormSubmission = new nsFSURLEncoded(charset, method, doc);
|
||||
*aFormSubmission = new nsFSURLEncoded(charset, method, doc,
|
||||
aOriginatingElement);
|
||||
}
|
||||
NS_ENSURE_TRUE(*aFormSubmission, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mounir Lamouri <mounir.lamouri@mozilla.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsFormSubmissionConstants_h__
|
||||
#define nsFormSubmissionConstants_h__
|
||||
|
||||
static const nsAttrValue::EnumTable kFormMethodTable[] = {
|
||||
{ "get", NS_FORM_METHOD_GET },
|
||||
{ "post", NS_FORM_METHOD_POST },
|
||||
{ 0 }
|
||||
};
|
||||
// Default method is 'get'.
|
||||
static const nsAttrValue::EnumTable* kFormDefaultMethod = &kFormMethodTable[0];
|
||||
|
||||
static const nsAttrValue::EnumTable kFormEnctypeTable[] = {
|
||||
{ "multipart/form-data", NS_FORM_ENCTYPE_MULTIPART },
|
||||
{ "application/x-www-form-urlencoded", NS_FORM_ENCTYPE_URLENCODED },
|
||||
{ "text/plain", NS_FORM_ENCTYPE_TEXTPLAIN },
|
||||
{ 0 }
|
||||
};
|
||||
// Default method is 'application/x-www-form-urlencoded'.
|
||||
static const nsAttrValue::EnumTable* kFormDefaultEnctype = &kFormEnctypeTable[1];
|
||||
|
||||
#endif // nsFormSubmissionConstants_h__
|
||||
|
|
@ -1916,7 +1916,8 @@ nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
|
|||
return;
|
||||
|
||||
nsPresContext* presContext = aData->mPresContext;
|
||||
if (!aData->mColorData->mBackImage && presContext->UseDocumentColors()) {
|
||||
if (aData->mColorData->mBackImage.GetUnit() == eCSSUnit_Null &&
|
||||
presContext->UseDocumentColors()) {
|
||||
// background
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::background);
|
||||
if (value && value->Type() == nsAttrValue::eString) {
|
||||
|
@ -1946,11 +1947,9 @@ nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
|
|||
doc->NodePrincipal(), doc);
|
||||
buffer->Release();
|
||||
if (NS_LIKELY(img != 0)) {
|
||||
// Use nsRuleDataColor's temporary mTempBackImage to
|
||||
// make a value list.
|
||||
aData->mColorData->mTempBackImage.mValue.SetImageValue(img);
|
||||
aData->mColorData->mBackImage =
|
||||
&aData->mColorData->mTempBackImage;
|
||||
nsCSSValueList* list =
|
||||
aData->mColorData->mBackImage.SetListValue();
|
||||
list->mValue.SetImageValue(img);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1958,10 +1957,8 @@ nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
|
|||
else if (presContext->CompatibilityMode() == eCompatibility_NavQuirks) {
|
||||
// in NavQuirks mode, allow the empty string to set the
|
||||
// background to empty
|
||||
// Use nsRuleDataColor's temporary mTempBackImage to make a value list.
|
||||
aData->mColorData->mBackImage = nsnull;
|
||||
aData->mColorData->mTempBackImage.mValue.SetNoneValue();
|
||||
aData->mColorData->mBackImage = &aData->mColorData->mTempBackImage;
|
||||
nsCSSValueList* list = aData->mColorData->mBackImage.SetListValue();
|
||||
list->mValue.SetNoneValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2706,8 +2703,10 @@ nsGenericHTMLFormElement::IsSingleLineTextControlInternal(PRBool aExcludePasswor
|
|||
PRInt32 aType) const
|
||||
{
|
||||
return aType == NS_FORM_INPUT_TEXT ||
|
||||
aType == NS_FORM_INPUT_EMAIL ||
|
||||
aType == NS_FORM_INPUT_SEARCH ||
|
||||
aType == NS_FORM_INPUT_TEL ||
|
||||
aType == NS_FORM_INPUT_URL ||
|
||||
(!aExcludePassword && aType == NS_FORM_INPUT_PASSWORD);
|
||||
}
|
||||
|
||||
|
|
|
@ -494,6 +494,19 @@ public:
|
|||
NS_HIDDEN_(nsresult) GetEditor(nsIEditor** aEditor);
|
||||
NS_HIDDEN_(nsresult) GetEditorInternal(nsIEditor** aEditor);
|
||||
|
||||
/**
|
||||
* Helper method for NS_IMPL_URI_ATTR macro.
|
||||
* Gets the absolute URI value of an attribute, by resolving any relative
|
||||
* URIs in the attribute against the baseuri of the element. If the attribute
|
||||
* isn't a relative URI the value of the attribute is returned as is. Only
|
||||
* works for attributes in null namespace.
|
||||
*
|
||||
* @param aAttr name of attribute.
|
||||
* @param aBaseAttr name of base attribute.
|
||||
* @param aResult result value [out]
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) GetURIAttr(nsIAtom* aAttr, nsIAtom* aBaseAttr, nsAString& aResult);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Add/remove this element to the documents name cache
|
||||
|
@ -654,19 +667,6 @@ protected:
|
|||
*/
|
||||
NS_HIDDEN_(nsresult) SetFloatAttr(nsIAtom* aAttr, float aValue);
|
||||
|
||||
/**
|
||||
* Helper method for NS_IMPL_URI_ATTR macro.
|
||||
* Gets the absolute URI value of an attribute, by resolving any relative
|
||||
* URIs in the attribute against the baseuri of the element. If the attribute
|
||||
* isn't a relative URI the value of the attribute is returned as is. Only
|
||||
* works for attributes in null namespace.
|
||||
*
|
||||
* @param aAttr name of attribute.
|
||||
* @param aBaseAttr name of base attribute.
|
||||
* @param aResult result value [out]
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) GetURIAttr(nsIAtom* aAttr, nsIAtom* aBaseAttr, nsAString& aResult);
|
||||
|
||||
/**
|
||||
* Helper for GetURIAttr and GetHrefURIForAnchors which returns an
|
||||
* nsIURI in the out param.
|
||||
|
@ -840,6 +840,11 @@ public:
|
|||
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
|
||||
/**
|
||||
* Returns if the control can be disabled.
|
||||
*/
|
||||
PRBool CanBeDisabled() const;
|
||||
|
||||
protected:
|
||||
virtual nsresult BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
|
@ -855,11 +860,6 @@ protected:
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the control can be disabled
|
||||
*/
|
||||
PRBool CanBeDisabled() const;
|
||||
|
||||
void UpdateEditableFormControlState();
|
||||
|
||||
PRBool IsSingleLineTextControlInternal(PRBool aExcludePassword, PRInt32 mType) const;
|
||||
|
|
|
@ -120,9 +120,10 @@ nsHTMLAudioElement::Initialize(nsISupports* aOwner, JSContext* aContext,
|
|||
JSObject *aObj, PRUint32 argc, jsval *argv)
|
||||
{
|
||||
// Audio elements created using "new Audio(...)" should have
|
||||
// 'autobuffer' set (since the script must intend to play the audio)
|
||||
nsresult rv = SetAttr(kNameSpaceID_None, nsGkAtoms::autobuffer,
|
||||
NS_LITERAL_STRING("autobuffer"), PR_TRUE);
|
||||
// 'preload' set to 'auto' (since the script must intend to
|
||||
// play the audio)
|
||||
nsresult rv = SetAttr(kNameSpaceID_None, nsGkAtoms::preload,
|
||||
NS_LITERAL_STRING("auto"), PR_TRUE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "nsIFormControl.h"
|
||||
#include "nsIForm.h"
|
||||
#include "nsFormSubmission.h"
|
||||
#include "nsFormSubmissionConstants.h"
|
||||
#include "nsIURL.h"
|
||||
|
||||
#include "nsIFrame.h"
|
||||
|
@ -61,6 +62,7 @@
|
|||
#include "nsLayoutErrors.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsHTMLFormElement.h"
|
||||
#include "nsConstraintValidation.h"
|
||||
|
||||
#define NS_IN_SUBMIT_CLICK (1 << 0)
|
||||
#define NS_OUTER_ACTIVATE_EVENT (1 << 1)
|
||||
|
@ -76,7 +78,8 @@ static const nsAttrValue::EnumTable kButtonTypeTable[] = {
|
|||
static const nsAttrValue::EnumTable* kButtonDefaultType = &kButtonTypeTable[2];
|
||||
|
||||
class nsHTMLButtonElement : public nsGenericHTMLFormElement,
|
||||
public nsIDOMHTMLButtonElement
|
||||
public nsIDOMHTMLButtonElement,
|
||||
public nsConstraintValidation
|
||||
{
|
||||
public:
|
||||
nsHTMLButtonElement(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
|
@ -100,11 +103,12 @@ public:
|
|||
// overriden nsIFormControl methods
|
||||
NS_IMETHOD_(PRUint32) GetType() const { return mType; }
|
||||
NS_IMETHOD Reset();
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement);
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
|
||||
NS_IMETHOD SaveState();
|
||||
PRBool RestoreState(nsPresState* aState);
|
||||
|
||||
PRInt32 IntrinsicState() const;
|
||||
|
||||
/**
|
||||
* Called when an attribute is about to be changed
|
||||
*/
|
||||
|
@ -128,6 +132,10 @@ public:
|
|||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
virtual void DoneCreatingElement();
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
// nsConstraintValidation
|
||||
PRBool IsBarredFromConstraintValidation();
|
||||
|
||||
protected:
|
||||
virtual PRBool AcceptAutofocus() const
|
||||
{
|
||||
|
@ -181,6 +189,9 @@ NS_INTERFACE_TABLE_HEAD(nsHTMLButtonElement)
|
|||
nsGenericHTMLFormElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLButtonElement)
|
||||
|
||||
// nsConstraintValidation
|
||||
NS_IMPL_NSCONSTRAINTVALIDATION(nsHTMLButtonElement)
|
||||
|
||||
// nsIDOMHTMLButtonElement
|
||||
|
||||
|
||||
|
@ -198,6 +209,12 @@ nsHTMLButtonElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
|||
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, AccessKey, accesskey)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLButtonElement, Autofocus, autofocus)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLButtonElement, Disabled, disabled)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, FormAction, formaction)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLButtonElement, FormEnctype, formenctype,
|
||||
kFormDefaultEnctype->tag)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLButtonElement, FormMethod, formmethod,
|
||||
kFormDefaultMethod->tag)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, FormTarget, formtarget)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, Name, name)
|
||||
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLButtonElement, TabIndex, tabindex, 0)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, Value, value)
|
||||
|
@ -273,17 +290,26 @@ nsHTMLButtonElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aAttribute == nsGkAtoms::type && kNameSpaceID_None == aNamespaceID) {
|
||||
// XXX ARG!! This is major evilness. ParseAttribute
|
||||
// shouldn't set members. Override SetAttr instead
|
||||
PRBool success = aResult.ParseEnumValue(aValue, kButtonTypeTable, PR_FALSE);
|
||||
if (success) {
|
||||
mType = aResult.GetEnumValue();
|
||||
} else {
|
||||
mType = kButtonDefaultType->value;
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aAttribute == nsGkAtoms::type) {
|
||||
// XXX ARG!! This is major evilness. ParseAttribute
|
||||
// shouldn't set members. Override SetAttr instead
|
||||
PRBool success = aResult.ParseEnumValue(aValue, kButtonTypeTable, PR_FALSE);
|
||||
if (success) {
|
||||
mType = aResult.GetEnumValue();
|
||||
} else {
|
||||
mType = kButtonDefaultType->value;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
return success;
|
||||
if (aAttribute == nsGkAtoms::formmethod) {
|
||||
return aResult.ParseEnumValue(aValue, kFormMethodTable, PR_FALSE);
|
||||
}
|
||||
if (aAttribute == nsGkAtoms::formenctype) {
|
||||
return aResult.ParseEnumValue(aValue, kFormEnctypeTable, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
|
||||
|
@ -330,7 +356,7 @@ nsHTMLButtonElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||
// tell the form that we are about to enter a click handler.
|
||||
// that means that if there are scripted submissions, the
|
||||
// latest one will be deferred until after the exit point of the handler.
|
||||
mForm->OnSubmitClickBegin();
|
||||
mForm->OnSubmitClickBegin(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -515,15 +541,14 @@ nsHTMLButtonElement::Reset()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLButtonElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement)
|
||||
nsHTMLButtonElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
//
|
||||
// We only submit if we were the button pressed
|
||||
//
|
||||
if (aSubmitElement != this) {
|
||||
if (aFormSubmission->GetOriginatingElement() != this) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -622,3 +647,19 @@ nsHTMLButtonElement::RestoreState(nsPresState* aState)
|
|||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsHTMLButtonElement::IntrinsicState() const
|
||||
{
|
||||
return NS_EVENT_STATE_OPTIONAL | nsGenericHTMLFormElement::IntrinsicState();
|
||||
}
|
||||
|
||||
// nsConstraintValidation
|
||||
|
||||
PRBool
|
||||
nsHTMLButtonElement::IsBarredFromConstraintValidation()
|
||||
{
|
||||
return (mType == NS_FORM_BUTTON_BUTTON ||
|
||||
mType == NS_FORM_BUTTON_RESET);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,10 +41,12 @@
|
|||
#include "nsStyleConsts.h"
|
||||
#include "nsIForm.h"
|
||||
#include "nsIFormControl.h"
|
||||
#include "nsConstraintValidation.h"
|
||||
|
||||
|
||||
class nsHTMLFieldSetElement : public nsGenericHTMLFormElement,
|
||||
public nsIDOMHTMLFieldSetElement
|
||||
public nsIDOMHTMLFieldSetElement,
|
||||
public nsConstraintValidation
|
||||
{
|
||||
public:
|
||||
nsHTMLFieldSetElement(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
|
@ -68,10 +70,12 @@ public:
|
|||
// nsIFormControl
|
||||
NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_FIELDSET; }
|
||||
NS_IMETHOD Reset();
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement);
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
// nsConstraintValidation
|
||||
PRBool IsBarredFromConstraintValidation() { return PR_TRUE; };
|
||||
};
|
||||
|
||||
// construction, destruction
|
||||
|
@ -107,6 +111,8 @@ NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLFieldSetElement)
|
|||
|
||||
// nsIDOMHTMLFieldSetElement
|
||||
|
||||
// nsConstraintValidation
|
||||
NS_IMPL_NSCONSTRAINTVALIDATION(nsHTMLFieldSetElement)
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(nsHTMLFieldSetElement)
|
||||
|
||||
|
@ -128,8 +134,7 @@ nsHTMLFieldSetElement::Reset()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFieldSetElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement)
|
||||
nsHTMLFieldSetElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#include "nsIWebProgress.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsFormData.h"
|
||||
#include "nsFormSubmissionConstants.h"
|
||||
|
||||
// radio buttons
|
||||
#include "nsIDOMHTMLInputElement.h"
|
||||
|
@ -80,23 +81,6 @@
|
|||
|
||||
static const int NS_FORM_CONTROL_LIST_HASHTABLE_SIZE = 16;
|
||||
|
||||
static const nsAttrValue::EnumTable kFormMethodTable[] = {
|
||||
{ "get", NS_FORM_METHOD_GET },
|
||||
{ "post", NS_FORM_METHOD_POST },
|
||||
{ 0 }
|
||||
};
|
||||
// Default method is 'get'.
|
||||
static const nsAttrValue::EnumTable* kFormDefaultMethod = &kFormMethodTable[0];
|
||||
|
||||
static const nsAttrValue::EnumTable kFormEnctypeTable[] = {
|
||||
{ "multipart/form-data", NS_FORM_ENCTYPE_MULTIPART },
|
||||
{ "application/x-www-form-urlencoded", NS_FORM_ENCTYPE_URLENCODED },
|
||||
{ "text/plain", NS_FORM_ENCTYPE_TEXTPLAIN },
|
||||
{ 0 }
|
||||
};
|
||||
// Default method is 'application/x-www-form-urlencoded'.
|
||||
static const nsAttrValue::EnumTable* kFormDefaultEnctype = &kFormEnctypeTable[1];
|
||||
|
||||
// nsHTMLFormElement
|
||||
|
||||
PRBool nsHTMLFormElement::gFirstFormSubmitted = PR_FALSE;
|
||||
|
@ -200,6 +184,7 @@ ShouldBeInElements(nsIFormControl* aFormControl)
|
|||
case NS_FORM_BUTTON_SUBMIT :
|
||||
case NS_FORM_INPUT_BUTTON :
|
||||
case NS_FORM_INPUT_CHECKBOX :
|
||||
case NS_FORM_INPUT_EMAIL :
|
||||
case NS_FORM_INPUT_FILE :
|
||||
case NS_FORM_INPUT_HIDDEN :
|
||||
case NS_FORM_INPUT_RESET :
|
||||
|
@ -209,6 +194,7 @@ ShouldBeInElements(nsIFormControl* aFormControl)
|
|||
case NS_FORM_INPUT_SUBMIT :
|
||||
case NS_FORM_INPUT_TEXT :
|
||||
case NS_FORM_INPUT_TEL :
|
||||
case NS_FORM_INPUT_URL :
|
||||
case NS_FORM_SELECT :
|
||||
case NS_FORM_TEXTAREA :
|
||||
case NS_FORM_FIELDSET :
|
||||
|
@ -373,6 +359,7 @@ nsHTMLFormElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
}
|
||||
|
||||
NS_IMPL_STRING_ATTR(nsHTMLFormElement, AcceptCharset, acceptcharset)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLFormElement, Action, action)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLFormElement, Enctype, enctype,
|
||||
kFormDefaultEnctype->tag)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLFormElement, Method, method,
|
||||
|
@ -381,7 +368,7 @@ NS_IMPL_STRING_ATTR(nsHTMLFormElement, Name, name)
|
|||
NS_IMPL_STRING_ATTR(nsHTMLFormElement, Target, target)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFormElement::GetAction(nsAString& aValue)
|
||||
nsHTMLFormElement::GetMozActionUri(nsAString& aValue)
|
||||
{
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::action, aValue);
|
||||
if (aValue.IsEmpty()) {
|
||||
|
@ -391,12 +378,6 @@ nsHTMLFormElement::GetAction(nsAString& aValue)
|
|||
return GetURIAttr(nsGkAtoms::action, nsnull, aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFormElement::SetAction(const nsAString& aValue)
|
||||
{
|
||||
return SetAttr(kNameSpaceID_None, nsGkAtoms::action, aValue, PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFormElement::Submit()
|
||||
{
|
||||
|
@ -707,7 +688,11 @@ nsHTMLFormElement::DoSubmit(nsEvent* aEvent)
|
|||
//
|
||||
// prepare the submission object
|
||||
//
|
||||
BuildSubmission(getter_Transfers(submission), aEvent);
|
||||
nsresult rv = BuildSubmission(getter_Transfers(submission), aEvent);
|
||||
if (NS_FAILED(rv)) {
|
||||
mIsSubmitting = PR_FALSE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// XXXbz if the script global is that for an sXBL/XBL2 doc, it won't
|
||||
// be a window...
|
||||
|
@ -744,10 +729,17 @@ nsHTMLFormElement::BuildSubmission(nsFormSubmission** aFormSubmission,
|
|||
NS_ASSERTION(!mPendingSubmission, "tried to build two submissions!");
|
||||
|
||||
// Get the originating frame (failure is non-fatal)
|
||||
nsIContent *originatingElement = nsnull;
|
||||
nsGenericHTMLElement* originatingElement = nsnull;
|
||||
if (aEvent) {
|
||||
if (NS_FORM_EVENT == aEvent->eventStructType) {
|
||||
originatingElement = ((nsFormEvent *)aEvent)->originator;
|
||||
nsIContent* originator = ((nsFormEvent *)aEvent)->originator;
|
||||
if (originator) {
|
||||
if (!originator->IsHTML()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
originatingElement =
|
||||
static_cast<nsGenericHTMLElement*>(((nsFormEvent *)aEvent)->originator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -756,13 +748,13 @@ nsHTMLFormElement::BuildSubmission(nsFormSubmission** aFormSubmission,
|
|||
//
|
||||
// Get the submission object
|
||||
//
|
||||
rv = GetSubmissionFromForm(this, aFormSubmission);
|
||||
rv = GetSubmissionFromForm(this, originatingElement, aFormSubmission);
|
||||
NS_ENSURE_SUBMIT_SUCCESS(rv);
|
||||
|
||||
//
|
||||
// Dump the data into the submission object
|
||||
//
|
||||
rv = WalkFormElements(*aFormSubmission, originatingElement);
|
||||
rv = WalkFormElements(*aFormSubmission);
|
||||
NS_ENSURE_SUBMIT_SUCCESS(rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -772,11 +764,13 @@ nsresult
|
|||
nsHTMLFormElement::SubmitSubmission(nsFormSubmission* aFormSubmission)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIContent* originatingElement = aFormSubmission->GetOriginatingElement();
|
||||
|
||||
//
|
||||
// Get the action and target
|
||||
//
|
||||
nsCOMPtr<nsIURI> actionURI;
|
||||
rv = GetActionURL(getter_AddRefs(actionURI));
|
||||
rv = GetActionURL(getter_AddRefs(actionURI), originatingElement);
|
||||
NS_ENSURE_SUBMIT_SUCCESS(rv);
|
||||
|
||||
if (!actionURI) {
|
||||
|
@ -810,8 +804,18 @@ nsHTMLFormElement::SubmitSubmission(nsFormSubmission* aFormSubmission)
|
|||
mIsSubmitting = PR_FALSE;
|
||||
}
|
||||
|
||||
// The target is the originating element formtarget attribute if the element
|
||||
// is a submit control and has such an attribute.
|
||||
// Otherwise, the target is the form owner's target attribute,
|
||||
// if it has such an attribute.
|
||||
// Finally, if one of the child nodes of the head element is a base element
|
||||
// with a target attribute, then the value of the target attribute of the
|
||||
// first such base element; or, if there is no such element, the empty string.
|
||||
nsAutoString target;
|
||||
if (!GetAttr(kNameSpaceID_None, nsGkAtoms::target, target)) {
|
||||
if (!(originatingElement && originatingElement->GetAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::formtarget,
|
||||
target)) &&
|
||||
!GetAttr(kNameSpaceID_None, nsGkAtoms::target, target)) {
|
||||
GetBaseTarget(target);
|
||||
}
|
||||
|
||||
|
@ -947,8 +951,7 @@ nsHTMLFormElement::NotifySubmitObservers(nsIURI* aActionURL,
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLFormElement::WalkFormElements(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement)
|
||||
nsHTMLFormElement::WalkFormElements(nsFormSubmission* aFormSubmission)
|
||||
{
|
||||
nsTArray<nsGenericHTMLFormElement*> sortedControls;
|
||||
nsresult rv = mControls->GetSortedControls(sortedControls);
|
||||
|
@ -960,7 +963,7 @@ nsHTMLFormElement::WalkFormElements(nsFormSubmission* aFormSubmission,
|
|||
PRUint32 len = sortedControls.Length();
|
||||
for (PRUint32 i = 0; i < len; ++i) {
|
||||
// Tell the control to submit its name/value pairs to the submission
|
||||
sortedControls[i]->SubmitNamesValues(aFormSubmission, aSubmitElement);
|
||||
sortedControls[i]->SubmitNamesValues(aFormSubmission);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1291,7 +1294,7 @@ nsHTMLFormElement::DoResolveName(const nsAString& aName,
|
|||
}
|
||||
|
||||
void
|
||||
nsHTMLFormElement::OnSubmitClickBegin()
|
||||
nsHTMLFormElement::OnSubmitClickBegin(nsIContent* aOriginatingElement)
|
||||
{
|
||||
mDeferSubmission = PR_TRUE;
|
||||
|
||||
|
@ -1301,7 +1304,7 @@ nsHTMLFormElement::OnSubmitClickBegin()
|
|||
nsCOMPtr<nsIURI> actionURI;
|
||||
nsresult rv;
|
||||
|
||||
rv = GetActionURL(getter_AddRefs(actionURI));
|
||||
rv = GetActionURL(getter_AddRefs(actionURI), aOriginatingElement);
|
||||
if (NS_FAILED(rv) || !actionURI)
|
||||
return;
|
||||
|
||||
|
@ -1335,7 +1338,8 @@ nsHTMLFormElement::FlushPendingSubmission()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLFormElement::GetActionURL(nsIURI** aActionURL)
|
||||
nsHTMLFormElement::GetActionURL(nsIURI** aActionURL,
|
||||
nsIContent* aOriginatingElement)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -1344,8 +1348,23 @@ nsHTMLFormElement::GetActionURL(nsIURI** aActionURL)
|
|||
//
|
||||
// Grab the URL string
|
||||
//
|
||||
// If the originating element is a submit control and has the formaction
|
||||
// attribute specified, it should be used. Otherwise, the action attribute
|
||||
// from the form element should be used.
|
||||
//
|
||||
nsAutoString action;
|
||||
GetAction(action);
|
||||
nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aOriginatingElement);
|
||||
if (formControl && formControl->IsSubmitControl() &&
|
||||
aOriginatingElement->GetAttr(kNameSpaceID_None, nsGkAtoms::formaction,
|
||||
action)) {
|
||||
// Avoid resolving action="" to the base uri, bug 297761.
|
||||
if (!action.IsEmpty()) {
|
||||
static_cast<nsGenericHTMLElement*>(aOriginatingElement)->
|
||||
GetURIAttr(nsGkAtoms::formaction, nsnull, action);
|
||||
}
|
||||
} else {
|
||||
GetMozActionUri(action);
|
||||
}
|
||||
|
||||
//
|
||||
// Form the full action URL
|
||||
|
@ -1488,7 +1507,7 @@ nsHTMLFormElement::GetFormData(nsIDOMFormData** aFormData)
|
|||
{
|
||||
nsRefPtr<nsFormData> fd = new nsFormData();
|
||||
|
||||
nsresult rv = WalkFormElements(fd, nsnull);
|
||||
nsresult rv = WalkFormElements(fd);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aFormData = fd.forget().get();
|
||||
|
|
|
@ -241,7 +241,7 @@ public:
|
|||
* submission. In that case the form will defer the submission until the
|
||||
* script handler returns and the return value is known.
|
||||
*/
|
||||
void OnSubmitClickBegin();
|
||||
void OnSubmitClickBegin(nsIContent* aOriginatingElement);
|
||||
void OnSubmitClickEnd();
|
||||
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
@ -304,10 +304,8 @@ protected:
|
|||
* their data pumped into the FormSubmitter.
|
||||
*
|
||||
* @param aFormSubmission the form submission object
|
||||
* @param aSubmitElement the element that was clicked on (nsnull if none)
|
||||
*/
|
||||
nsresult WalkFormElements(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement);
|
||||
nsresult WalkFormElements(nsFormSubmission* aFormSubmission);
|
||||
|
||||
/**
|
||||
* Notify any submit observers of the submit.
|
||||
|
@ -328,8 +326,9 @@ protected:
|
|||
* Get the full URL to submit to. Do not submit if the returned URL is null.
|
||||
*
|
||||
* @param aActionURL the full, unadulterated URL you'll be submitting to [OUT]
|
||||
* @param aOriginatingElement the originating element of the form submission [IN]
|
||||
*/
|
||||
nsresult GetActionURL(nsIURI** aActionURL);
|
||||
nsresult GetActionURL(nsIURI** aActionURL, nsIContent* aOriginatingElement);
|
||||
|
||||
public:
|
||||
/**
|
||||
|
|
|
@ -283,8 +283,8 @@ MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
|||
// 100% on all corners
|
||||
nsCSSCornerSizes& corners = aData->mMarginData->mBorderRadius;
|
||||
|
||||
NS_FOR_CSS_HALF_CORNERS(hc) {
|
||||
nsCSSValue& dimen = corners.GetHalfCorner(hc);
|
||||
NS_FOR_CSS_FULL_CORNERS(c) {
|
||||
nsCSSValue& dimen = corners.GetCorner(c);
|
||||
if (dimen.GetUnit() == eCSSUnit_Null) {
|
||||
dimen.SetPercentValue(1.0f);
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "nsIFormControl.h"
|
||||
#include "nsIForm.h"
|
||||
#include "nsFormSubmission.h"
|
||||
#include "nsFormSubmissionConstants.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIFormControlFrame.h"
|
||||
|
@ -69,6 +70,7 @@
|
|||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsIIOService.h"
|
||||
|
||||
#include "nsPresState.h"
|
||||
#include "nsLayoutErrors.h"
|
||||
|
@ -107,9 +109,17 @@
|
|||
#include "mozAutoDocUpdate.h"
|
||||
#include "nsHTMLFormElement.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#include "nsTextEditRules.h"
|
||||
|
||||
// JS headers are needed for the pattern attribute.
|
||||
#include "jsapi.h" // for js_SaveAndClearRegExpStatics
|
||||
// and js_RestoreRegExpStatics
|
||||
#include "jsregexp.h" // for js::AutoValueRooter
|
||||
#include "jscntxt.h"
|
||||
|
||||
#include "nsHTMLInputElement.h"
|
||||
|
||||
// XXX align=left, hspace, vspace, border? other nav4 attrs
|
||||
|
@ -133,6 +143,7 @@ static PRInt32 gSelectTextFieldOnFocus;
|
|||
static const nsAttrValue::EnumTable kInputTypeTable[] = {
|
||||
{ "button", NS_FORM_INPUT_BUTTON },
|
||||
{ "checkbox", NS_FORM_INPUT_CHECKBOX },
|
||||
{ "email", NS_FORM_INPUT_EMAIL },
|
||||
{ "file", NS_FORM_INPUT_FILE },
|
||||
{ "hidden", NS_FORM_INPUT_HIDDEN },
|
||||
{ "reset", NS_FORM_INPUT_RESET },
|
||||
|
@ -143,11 +154,12 @@ static const nsAttrValue::EnumTable kInputTypeTable[] = {
|
|||
{ "submit", NS_FORM_INPUT_SUBMIT },
|
||||
{ "tel", NS_FORM_INPUT_TEL },
|
||||
{ "text", NS_FORM_INPUT_TEXT },
|
||||
{ "url", NS_FORM_INPUT_URL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
// Default type is 'text'.
|
||||
static const nsAttrValue::EnumTable* kInputDefaultType = &kInputTypeTable[11];
|
||||
static const nsAttrValue::EnumTable* kInputDefaultType = &kInputTypeTable[12];
|
||||
|
||||
#define NS_INPUT_ELEMENT_STATE_IID \
|
||||
{ /* dc3b3d14-23e2-4479-b513-7b369343e3a0 */ \
|
||||
|
@ -298,6 +310,8 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLInputElement)
|
|||
nsGenericHTMLFormElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLInputElement)
|
||||
|
||||
// nsConstraintValidation
|
||||
NS_IMPL_NSCONSTRAINTVALIDATION(nsHTMLInputElement)
|
||||
|
||||
// nsIDOMNode
|
||||
|
||||
|
@ -317,10 +331,12 @@ nsHTMLInputElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
switch (mType) {
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_URL:
|
||||
if (GET_BOOLBIT(mBitField, BF_VALUE_CHANGED)) {
|
||||
// We don't have our default value anymore. Set our value on
|
||||
// the clone.
|
||||
|
@ -450,10 +466,12 @@ nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
// If we are changing type from File/Text/Tel/Passwd to other input types
|
||||
// we need save the mValue into value attribute
|
||||
if (mInputData.mValue &&
|
||||
mType != NS_FORM_INPUT_EMAIL &&
|
||||
mType != NS_FORM_INPUT_TEXT &&
|
||||
mType != NS_FORM_INPUT_SEARCH &&
|
||||
mType != NS_FORM_INPUT_PASSWORD &&
|
||||
mType != NS_FORM_INPUT_TEL &&
|
||||
mType != NS_FORM_INPUT_URL &&
|
||||
mType != NS_FORM_INPUT_FILE) {
|
||||
SetAttr(kNameSpaceID_None, nsGkAtoms::value,
|
||||
NS_ConvertUTF8toUTF16(mInputData.mValue), PR_FALSE);
|
||||
|
@ -491,7 +509,9 @@ nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
NS_EVENT_STATE_LOADING |
|
||||
NS_EVENT_STATE_INDETERMINATE |
|
||||
NS_EVENT_STATE_MOZ_READONLY |
|
||||
NS_EVENT_STATE_MOZ_READWRITE);
|
||||
NS_EVENT_STATE_MOZ_READWRITE |
|
||||
NS_EVENT_STATE_REQUIRED |
|
||||
NS_EVENT_STATE_OPTIONAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -532,15 +552,23 @@ NS_IMPL_STRING_ATTR(nsHTMLInputElement, Alt, alt)
|
|||
NS_IMPL_BOOL_ATTR(nsHTMLInputElement, Autofocus, autofocus)
|
||||
//NS_IMPL_BOOL_ATTR(nsHTMLInputElement, Checked, checked)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLInputElement, Disabled, disabled)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLInputElement, FormAction, formaction)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLInputElement, FormEnctype, formenctype,
|
||||
kFormDefaultEnctype->tag)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLInputElement, FormMethod, formmethod,
|
||||
kFormDefaultMethod->tag)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLInputElement, FormTarget, formtarget)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLInputElement, Multiple, multiple)
|
||||
NS_IMPL_NON_NEGATIVE_INT_ATTR(nsHTMLInputElement, MaxLength, maxlength)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLInputElement, Name, name)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLInputElement, ReadOnly, readonly)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLInputElement, Required, required)
|
||||
NS_IMPL_URI_ATTR(nsHTMLInputElement, Src, src)
|
||||
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLInputElement, TabIndex, tabindex, 0)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLInputElement, UseMap, usemap)
|
||||
//NS_IMPL_STRING_ATTR(nsHTMLInputElement, Value, value)
|
||||
//NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLInputElement, Size, size, 0)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLInputElement, Pattern, pattern)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLInputElement, Placeholder, placeholder)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLInputElement, Type, type,
|
||||
kInputDefaultType->tag)
|
||||
|
@ -1082,17 +1110,7 @@ nsHTMLInputElement::RadioSetChecked(PRBool aNotify)
|
|||
//
|
||||
// Find the selected radio button so we can deselect it
|
||||
//
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> currentlySelected;
|
||||
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
|
||||
// This is ONLY INITIALIZED IF container EXISTS
|
||||
nsAutoString name;
|
||||
PRBool nameExists = PR_FALSE;
|
||||
if (container) {
|
||||
nameExists = GetNameIfExists(name);
|
||||
if (nameExists) {
|
||||
container->GetCurrentRadioButton(name, getter_AddRefs(currentlySelected));
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> currentlySelected = GetSelectedRadioButton();
|
||||
|
||||
//
|
||||
// Deselect the currently selected radio button
|
||||
|
@ -1115,7 +1133,9 @@ nsHTMLInputElement::RadioSetChecked(PRBool aNotify)
|
|||
// Let the group know that we are now the One True Radio Button
|
||||
//
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (container && nameExists) {
|
||||
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
|
||||
nsAutoString name;
|
||||
if (container && GetNameIfExists(name)) {
|
||||
rv = container->SetCurrentRadioButton(name, this);
|
||||
}
|
||||
|
||||
|
@ -1137,6 +1157,25 @@ nsHTMLInputElement::GetRadioGroupContainer()
|
|||
return retval;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMHTMLInputElement>
|
||||
nsHTMLInputElement::GetSelectedRadioButton()
|
||||
{
|
||||
nsIDOMHTMLInputElement* selected;
|
||||
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
|
||||
|
||||
if (!container) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsAutoString name;
|
||||
if (!GetNameIfExists(name)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
container->GetCurrentRadioButton(name, &selected);
|
||||
return selected;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLInputElement::MaybeSubmitForm(nsPresContext* aPresContext)
|
||||
{
|
||||
|
@ -1500,16 +1539,8 @@ nsHTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||
|
||||
case NS_FORM_INPUT_RADIO:
|
||||
{
|
||||
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
|
||||
if (container) {
|
||||
nsAutoString name;
|
||||
if (GetNameIfExists(name)) {
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton;
|
||||
container->GetCurrentRadioButton(name,
|
||||
getter_AddRefs(selectedRadioButton));
|
||||
aVisitor.mItemData = selectedRadioButton;
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton = GetSelectedRadioButton();
|
||||
aVisitor.mItemData = selectedRadioButton;
|
||||
|
||||
originalCheckedValue = GetChecked();
|
||||
if (!originalCheckedValue) {
|
||||
|
@ -1525,7 +1556,7 @@ nsHTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||
// tell the form that we are about to enter a click handler.
|
||||
// that means that if there are scripted submissions, the
|
||||
// latest one will be deferred until after the exit point of the handler.
|
||||
mForm->OnSubmitClickBegin();
|
||||
mForm->OnSubmitClickBegin(this);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1831,9 +1862,11 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
|||
(keyEvent->keyCode == NS_VK_RETURN ||
|
||||
keyEvent->keyCode == NS_VK_ENTER) &&
|
||||
(mType == NS_FORM_INPUT_TEXT ||
|
||||
mType == NS_FORM_INPUT_EMAIL ||
|
||||
mType == NS_FORM_INPUT_SEARCH ||
|
||||
mType == NS_FORM_INPUT_PASSWORD ||
|
||||
mType == NS_FORM_INPUT_TEL ||
|
||||
mType == NS_FORM_INPUT_URL ||
|
||||
mType == NS_FORM_INPUT_FILE)) {
|
||||
|
||||
PRBool isButton = PR_FALSE;
|
||||
|
@ -2045,11 +2078,20 @@ nsHTMLInputElement::SanitizeValue(nsAString& aValue)
|
|||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
{
|
||||
PRUnichar crlf[] = { PRUnichar('\r'), PRUnichar('\n'), 0 };
|
||||
aValue.StripChars(crlf);
|
||||
}
|
||||
break;
|
||||
case NS_FORM_INPUT_URL:
|
||||
{
|
||||
PRUnichar crlf[] = { PRUnichar('\r'), PRUnichar('\n'), 0 };
|
||||
aValue.StripChars(crlf);
|
||||
|
||||
aValue = nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2108,6 +2150,12 @@ nsHTMLInputElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
if (aAttribute == nsGkAtoms::align) {
|
||||
return ParseAlignValue(aValue, aResult);
|
||||
}
|
||||
if (aAttribute == nsGkAtoms::formmethod) {
|
||||
return aResult.ParseEnumValue(aValue, kFormMethodTable, PR_FALSE);
|
||||
}
|
||||
if (aAttribute == nsGkAtoms::formenctype) {
|
||||
return aResult.ParseEnumValue(aValue, kFormEnctypeTable, PR_FALSE);
|
||||
}
|
||||
if (ParseImageAttribute(aAttribute, aValue, aResult)) {
|
||||
// We have to call |ParseImageAttribute| unconditionally since we
|
||||
// don't know if we're going to have a type="image" attribute yet,
|
||||
|
@ -2384,8 +2432,10 @@ nsHTMLInputElement::SetDefaultValueAsValue()
|
|||
}
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_URL:
|
||||
{
|
||||
nsAutoString resetVal;
|
||||
GetDefaultValue(resetVal);
|
||||
|
@ -2420,8 +2470,10 @@ nsHTMLInputElement::Reset()
|
|||
break;
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_URL:
|
||||
SetValueChanged(PR_FALSE);
|
||||
break;
|
||||
default:
|
||||
|
@ -2432,8 +2484,7 @@ nsHTMLInputElement::Reset()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLInputElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement)
|
||||
nsHTMLInputElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -2447,7 +2498,7 @@ nsHTMLInputElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
|||
if (disabled || mType == NS_FORM_INPUT_RESET ||
|
||||
mType == NS_FORM_INPUT_BUTTON ||
|
||||
((mType == NS_FORM_INPUT_SUBMIT || mType == NS_FORM_INPUT_IMAGE) &&
|
||||
aSubmitElement != this) ||
|
||||
aFormSubmission->GetOriginatingElement() != this) ||
|
||||
((mType == NS_FORM_INPUT_RADIO || mType == NS_FORM_INPUT_CHECKBOX) &&
|
||||
!GetChecked())) {
|
||||
return NS_OK;
|
||||
|
@ -2586,9 +2637,11 @@ nsHTMLInputElement::SaveState()
|
|||
// Never save passwords in session history
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
break;
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_URL:
|
||||
case NS_FORM_INPUT_HIDDEN:
|
||||
{
|
||||
if (GET_BOOLBIT(mBitField, BF_VALUE_CHANGED)) {
|
||||
|
@ -2701,6 +2754,12 @@ nsHTMLInputElement::IntrinsicState() const
|
|||
state |= nsImageLoadingContent::ImageState();
|
||||
}
|
||||
|
||||
if (DoesRequiredApply() && HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
|
||||
state |= NS_EVENT_STATE_REQUIRED;
|
||||
} else {
|
||||
state |= NS_EVENT_STATE_OPTIONAL;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -2724,9 +2783,11 @@ nsHTMLInputElement::RestoreState(nsPresState* aState)
|
|||
break;
|
||||
}
|
||||
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_URL:
|
||||
case NS_FORM_INPUT_HIDDEN:
|
||||
{
|
||||
SetValueInternal(inputState->GetValue(), PR_FALSE, PR_TRUE);
|
||||
|
@ -2956,6 +3017,468 @@ nsHTMLInputElement::VisitGroup(nsIRadioVisitor* aVisitor, PRBool aFlushContent)
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsHTMLInputElement::ValueModeType
|
||||
nsHTMLInputElement::GetValueMode() const
|
||||
{
|
||||
switch (mType)
|
||||
{
|
||||
case NS_FORM_INPUT_HIDDEN:
|
||||
case NS_FORM_INPUT_SUBMIT:
|
||||
case NS_FORM_INPUT_BUTTON:
|
||||
case NS_FORM_INPUT_RESET:
|
||||
case NS_FORM_INPUT_IMAGE:
|
||||
return VALUE_MODE_DEFAULT;
|
||||
case NS_FORM_INPUT_CHECKBOX:
|
||||
case NS_FORM_INPUT_RADIO:
|
||||
return VALUE_MODE_DEFAULT_ON;
|
||||
case NS_FORM_INPUT_FILE:
|
||||
return VALUE_MODE_FILENAME;
|
||||
#ifdef DEBUG
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_URL:
|
||||
return VALUE_MODE_VALUE;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in GetValueMode()");
|
||||
return VALUE_MODE_VALUE;
|
||||
#else // DEBUG
|
||||
default:
|
||||
return VALUE_MODE_VALUE;
|
||||
#endif // DEBUG
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLInputElement::IsMutable() const
|
||||
{
|
||||
return !HasAttr(kNameSpaceID_None, nsGkAtoms::disabled) &&
|
||||
GetCurrentDoc() &&
|
||||
!(DoesReadOnlyApply() &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::readonly));
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLInputElement::DoesReadOnlyApply() const
|
||||
{
|
||||
switch (mType)
|
||||
{
|
||||
case NS_FORM_INPUT_HIDDEN:
|
||||
case NS_FORM_INPUT_BUTTON:
|
||||
case NS_FORM_INPUT_IMAGE:
|
||||
case NS_FORM_INPUT_RESET:
|
||||
case NS_FORM_INPUT_SUBMIT:
|
||||
case NS_FORM_INPUT_RADIO:
|
||||
case NS_FORM_INPUT_FILE:
|
||||
case NS_FORM_INPUT_CHECKBOX:
|
||||
// TODO:
|
||||
// case NS_FORM_INPUT_COLOR:
|
||||
// case NS_FORM_INPUT_RANGE:
|
||||
return PR_FALSE;
|
||||
#ifdef DEBUG
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_URL:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in DoesReadOnlyApply()");
|
||||
return PR_TRUE;
|
||||
#else // DEBUG
|
||||
default:
|
||||
return PR_TRUE;
|
||||
#endif // DEBUG
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLInputElement::DoesRequiredApply() const
|
||||
{
|
||||
switch (mType)
|
||||
{
|
||||
case NS_FORM_INPUT_HIDDEN:
|
||||
case NS_FORM_INPUT_BUTTON:
|
||||
case NS_FORM_INPUT_IMAGE:
|
||||
case NS_FORM_INPUT_RESET:
|
||||
case NS_FORM_INPUT_SUBMIT:
|
||||
// TODO:
|
||||
// case NS_FORM_INPUT_COLOR:
|
||||
// case NS_FORM_INPUT_RANGE:
|
||||
return PR_FALSE;
|
||||
#ifdef DEBUG
|
||||
case NS_FORM_INPUT_RADIO:
|
||||
case NS_FORM_INPUT_CHECKBOX:
|
||||
case NS_FORM_INPUT_FILE:
|
||||
case NS_FORM_INPUT_TEXT:
|
||||
case NS_FORM_INPUT_PASSWORD:
|
||||
case NS_FORM_INPUT_SEARCH:
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_URL:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in DoesRequiredApply()");
|
||||
return PR_TRUE;
|
||||
#else // DEBUG
|
||||
default:
|
||||
return PR_TRUE;
|
||||
#endif // DEBUG
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLInputElement::DoesPatternApply() const
|
||||
{
|
||||
return IsSingleLineTextControl(PR_FALSE);
|
||||
}
|
||||
|
||||
// nsConstraintValidation
|
||||
|
||||
PRBool
|
||||
nsHTMLInputElement::IsTooLong()
|
||||
{
|
||||
if (!GET_BOOLBIT(mBitField, BF_VALUE_CHANGED)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRInt32 maxLength = -1;
|
||||
PRInt32 textLength = -1;
|
||||
|
||||
GetMaxLength(&maxLength);
|
||||
GetTextLength(&textLength);
|
||||
|
||||
return (maxLength >= 0) && (textLength > maxLength);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLInputElement::IsValueMissing()
|
||||
{
|
||||
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::required) ||
|
||||
!DoesRequiredApply()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (GetValueMode() == VALUE_MODE_VALUE) {
|
||||
if (!IsMutable()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsAutoString value;
|
||||
nsresult rv = GetValue(value);
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
|
||||
return value.IsEmpty();
|
||||
}
|
||||
|
||||
if (mType == NS_FORM_INPUT_CHECKBOX) {
|
||||
return !GetChecked();
|
||||
}
|
||||
|
||||
if (mType == NS_FORM_INPUT_RADIO) {
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> selected = GetSelectedRadioButton();
|
||||
return !selected;
|
||||
}
|
||||
|
||||
if (mType == NS_FORM_INPUT_FILE) {
|
||||
nsCOMArray<nsIFile> files;
|
||||
GetFileArray(files);
|
||||
return !files.Count();
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLInputElement::HasTypeMismatch()
|
||||
{
|
||||
if (mType == NS_FORM_INPUT_EMAIL) {
|
||||
nsAutoString value;
|
||||
NS_ENSURE_SUCCESS(GetValue(value), PR_FALSE);
|
||||
|
||||
if (value.IsEmpty()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::multiple) ?
|
||||
!IsValidEmailAddressList(value) :
|
||||
!IsValidEmailAddress(value);
|
||||
} else if (mType == NS_FORM_INPUT_URL) {
|
||||
nsAutoString value;
|
||||
NS_ENSURE_SUCCESS(GetValue(value), PR_FALSE);
|
||||
|
||||
if (value.IsEmpty()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
* The URL is not checked as the HTML5 specifications want it to be because
|
||||
* there is no code to check for a valid URI/IRI according to 3986 and 3987
|
||||
* RFC's at the moment, see bug 561586.
|
||||
*
|
||||
* RFC 3987 (IRI) implementation: bug 42899
|
||||
*
|
||||
* HTML5 specifications:
|
||||
* http://dev.w3.org/html5/spec/infrastructure.html#valid-url
|
||||
*/
|
||||
nsCOMPtr<nsIIOService> ioService = do_GetIOService();
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
|
||||
return !NS_SUCCEEDED(ioService->NewURI(NS_ConvertUTF16toUTF8(value), nsnull,
|
||||
nsnull, getter_AddRefs(uri)));
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLInputElement::HasPatternMismatch()
|
||||
{
|
||||
nsAutoString pattern;
|
||||
if (!DoesPatternApply() || !GetAttr(kNameSpaceID_None, nsGkAtoms::pattern,
|
||||
pattern)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsAutoString value;
|
||||
NS_ENSURE_SUCCESS(GetValue(value), PR_FALSE);
|
||||
|
||||
if (value.IsEmpty()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsIDocument* doc = GetOwnerDoc();
|
||||
if (!doc) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return !IsPatternMatching(value, pattern, doc);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLInputElement::IsBarredFromConstraintValidation()
|
||||
{
|
||||
return mType == NS_FORM_INPUT_HIDDEN ||
|
||||
mType == NS_FORM_INPUT_BUTTON ||
|
||||
mType == NS_FORM_INPUT_RESET ||
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLInputElement::GetValidationMessage(nsAString& aValidationMessage,
|
||||
ValidationMessageType aType)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
switch (aType)
|
||||
{
|
||||
case VALIDATION_MESSAGE_TOO_LONG:
|
||||
{
|
||||
nsXPIDLString message;
|
||||
PRInt32 maxLength = -1;
|
||||
PRInt32 textLength = -1;
|
||||
nsAutoString strMaxLength;
|
||||
nsAutoString strTextLength;
|
||||
|
||||
GetMaxLength(&maxLength);
|
||||
GetTextLength(&textLength);
|
||||
|
||||
strMaxLength.AppendInt(maxLength);
|
||||
strTextLength.AppendInt(textLength);
|
||||
|
||||
const PRUnichar* params[] = { strTextLength.get(), strMaxLength.get() };
|
||||
rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"ElementSuffersFromBeingTooLong",
|
||||
params, 2, message);
|
||||
aValidationMessage = message;
|
||||
break;
|
||||
}
|
||||
case VALIDATION_MESSAGE_VALUE_MISSING:
|
||||
{
|
||||
nsXPIDLString message;
|
||||
nsCAutoString key;
|
||||
switch (mType)
|
||||
{
|
||||
case NS_FORM_INPUT_FILE:
|
||||
key.Assign("FileElementSuffersFromBeingMissing");
|
||||
break;
|
||||
case NS_FORM_INPUT_CHECKBOX:
|
||||
key.Assign("CheckboxElementSuffersFromBeingMissing");
|
||||
break;
|
||||
case NS_FORM_INPUT_RADIO:
|
||||
key.Assign("RadioElementSuffersFromBeingMissing");
|
||||
break;
|
||||
default:
|
||||
key.Assign("TextElementSuffersFromBeingMissing");
|
||||
}
|
||||
rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
key.get(), message);
|
||||
aValidationMessage = message;
|
||||
break;
|
||||
}
|
||||
case VALIDATION_MESSAGE_TYPE_MISMATCH:
|
||||
{
|
||||
nsXPIDLString message;
|
||||
nsCAutoString key;
|
||||
if (mType == NS_FORM_INPUT_EMAIL) {
|
||||
key.AssignLiteral("ElementSuffersFromInvalidEmail");
|
||||
} else if (mType == NS_FORM_INPUT_URL) {
|
||||
key.AssignLiteral("ElementSuffersFromInvalidURL");
|
||||
} else {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
key.get(), message);
|
||||
aValidationMessage = message;
|
||||
break;
|
||||
}
|
||||
case VALIDATION_MESSAGE_PATTERN_MISMATCH:
|
||||
{
|
||||
nsXPIDLString message;
|
||||
nsAutoString title;
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
|
||||
if (title.IsEmpty()) {
|
||||
rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"ElementSuffersFromPatternMismatch",
|
||||
message);
|
||||
} else {
|
||||
const PRUnichar* params[] = { title.get() };
|
||||
rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"ElementSuffersFromPatternMismatchWithTitle",
|
||||
params, 1, message);
|
||||
}
|
||||
aValidationMessage = message;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rv = nsConstraintValidation::GetValidationMessage(aValidationMessage, aType);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//static
|
||||
PRBool
|
||||
nsHTMLInputElement::IsValidEmailAddressList(const nsAString& aValue)
|
||||
{
|
||||
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
|
||||
tokenizer(aValue, ',');
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
if (!IsValidEmailAddress(tokenizer.nextToken())) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return !tokenizer.lastTokenEndedWithSeparator();
|
||||
}
|
||||
|
||||
//static
|
||||
PRBool
|
||||
nsHTMLInputElement::IsValidEmailAddress(const nsAString& aValue)
|
||||
{
|
||||
PRUint32 i = 0;
|
||||
PRUint32 length = aValue.Length();
|
||||
|
||||
// If the email address is empty, begins with a '@' or ends with a '.',
|
||||
// we know it's invalid.
|
||||
if (length == 0 || aValue[0] == '@' || aValue[length-1] == '.') {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Parsing the username.
|
||||
for (; i < length && aValue[i] != '@'; ++i) {
|
||||
PRUnichar c = aValue[i];
|
||||
|
||||
// The username characters have to be in this list to be valid.
|
||||
if (!(nsCRT::IsAsciiAlpha(c) || nsCRT::IsAsciiDigit(c) ||
|
||||
c == '.' || c == '!' || c == '#' || c == '$' || c == '%' ||
|
||||
c == '&' || c == '\''|| c == '*' || c == '+' || c == '-' ||
|
||||
c == '/' || c == '=' || c == '?' || c == '^' || c == '_' ||
|
||||
c == '`' || c == '{' || c == '|' || c == '}' || c == '~' )) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// There is no domain name (or it's one-character long),
|
||||
// that's not a valid email address.
|
||||
if (++i >= length) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// The domain name can't begin with a dot.
|
||||
if (aValue[i] == '.') {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// The domain name must have at least one dot which can't follow another dot,
|
||||
// can't be the first nor the last domain name character.
|
||||
PRBool dotFound = PR_FALSE;
|
||||
|
||||
// Parsing the domain name.
|
||||
for (; i < length; ++i) {
|
||||
PRUnichar c = aValue[i];
|
||||
|
||||
if (c == '.') {
|
||||
dotFound = PR_TRUE;
|
||||
// A dot can't follow a dot.
|
||||
if (aValue[i-1] == '.') {
|
||||
return PR_FALSE;
|
||||
}
|
||||
} else if (!(nsCRT::IsAsciiAlpha(c) || nsCRT::IsAsciiDigit(c) ||
|
||||
c == '-')) {
|
||||
// The domain characters have to be in this list to be valid.
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return dotFound;
|
||||
}
|
||||
|
||||
//static
|
||||
PRBool
|
||||
nsHTMLInputElement::IsPatternMatching(nsAString& aValue, nsAString& aPattern,
|
||||
nsIDocument* aDocument)
|
||||
{
|
||||
NS_ASSERTION(aDocument, "aDocument should be a valid pointer (not null)");
|
||||
NS_ENSURE_TRUE(aDocument->GetScriptGlobalObject(), PR_TRUE);
|
||||
|
||||
JSContext* ctx = (JSContext*) aDocument->GetScriptGlobalObject()->
|
||||
GetContext()->GetNativeContext();
|
||||
NS_ENSURE_TRUE(ctx, PR_TRUE);
|
||||
|
||||
JSAutoRequest ar(ctx);
|
||||
|
||||
// The pattern has to match the entire value.
|
||||
aPattern.Insert(NS_LITERAL_STRING("^(?:"), 0);
|
||||
aPattern.Append(NS_LITERAL_STRING(")$"));
|
||||
|
||||
JSObject* re = JS_NewUCRegExpObject(ctx, reinterpret_cast<jschar*>
|
||||
(aPattern.BeginWriting()),
|
||||
aPattern.Length(), 0);
|
||||
NS_ENSURE_TRUE(re, PR_TRUE);
|
||||
|
||||
js::AutoObjectRooter re_root(ctx, re);
|
||||
js::AutoStringRooter tvr(ctx);
|
||||
js::RegExpStatics statics(ctx);
|
||||
jsval rval = JSVAL_NULL;
|
||||
size_t idx = 0;
|
||||
JSBool res;
|
||||
|
||||
js_SaveAndClearRegExpStatics(ctx, &statics, &tvr);
|
||||
|
||||
res = JS_ExecuteRegExp(ctx, re, reinterpret_cast<jschar*>
|
||||
(aValue.BeginWriting()),
|
||||
aValue.Length(), &idx, JS_TRUE, &rval);
|
||||
|
||||
js_RestoreRegExpStatics(ctx, &statics);
|
||||
|
||||
return res == JS_FALSE || rval != JSVAL_NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Visitor classes
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
#include "nsTextEditorState.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsConstraintValidation.h"
|
||||
|
||||
//
|
||||
// Accessors for mBitField
|
||||
|
@ -80,7 +81,8 @@ class nsHTMLInputElement : public nsGenericHTMLFormElement,
|
|||
public nsITextControlElement,
|
||||
public nsIPhonetic,
|
||||
public nsIDOMNSEditableElement,
|
||||
public nsIFileControlElement
|
||||
public nsIFileControlElement,
|
||||
public nsConstraintValidation
|
||||
{
|
||||
public:
|
||||
nsHTMLInputElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
|
@ -115,8 +117,7 @@ public:
|
|||
// Overriden nsIFormControl methods
|
||||
NS_IMETHOD_(PRUint32) GetType() const { return mType; }
|
||||
NS_IMETHOD Reset();
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement);
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
|
||||
NS_IMETHOD SaveState();
|
||||
virtual PRBool RestoreState(nsPresState* aState);
|
||||
virtual PRBool AllowDrop();
|
||||
|
@ -186,6 +187,15 @@ public:
|
|||
*/
|
||||
virtual already_AddRefed<nsIRadioGroupContainer> GetRadioGroupContainer();
|
||||
|
||||
/**
|
||||
* Helper function returning the currently selected button in the radio group.
|
||||
* Returning null if the element is not a button or if there is no selectied
|
||||
* button in the group.
|
||||
*
|
||||
* @return the selected button (or null).
|
||||
*/
|
||||
already_AddRefed<nsIDOMHTMLInputElement> GetSelectedRadioButton();
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
virtual void UpdateEditableState()
|
||||
|
@ -200,11 +210,82 @@ public:
|
|||
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
// nsConstraintValidation
|
||||
PRBool IsTooLong();
|
||||
PRBool IsValueMissing();
|
||||
PRBool HasTypeMismatch();
|
||||
PRBool HasPatternMismatch();
|
||||
PRBool IsBarredFromConstraintValidation();
|
||||
nsresult GetValidationMessage(nsAString& aValidationMessage,
|
||||
ValidationMessageType aType);
|
||||
|
||||
protected:
|
||||
// Pull IsSingleLineTextControl into our scope, otherwise it'd be hidden
|
||||
// by the nsITextControlElement version.
|
||||
using nsGenericHTMLFormElement::IsSingleLineTextControl;
|
||||
|
||||
/**
|
||||
* The ValueModeType specifies how the value IDL attribute should behave.
|
||||
*
|
||||
* See: http://dev.w3.org/html5/spec/forms.html#dom-input-value
|
||||
*/
|
||||
enum ValueModeType
|
||||
{
|
||||
// On getting, returns the value.
|
||||
// On setting, sets value.
|
||||
VALUE_MODE_VALUE,
|
||||
// On getting, returns the value if present or the empty string.
|
||||
// On setting, sets the value.
|
||||
VALUE_MODE_DEFAULT,
|
||||
// On getting, returns the value if present or "on".
|
||||
// On setting, sets the value.
|
||||
VALUE_MODE_DEFAULT_ON,
|
||||
// On getting, returns "C:\fakepath\" followed by the file name of the
|
||||
// first file of the selected files if any.
|
||||
// On setting the empty string, empties the selected files list, otherwise
|
||||
// throw the INVALID_STATE_ERR exception.
|
||||
VALUE_MODE_FILENAME
|
||||
};
|
||||
|
||||
/**
|
||||
* This helper method returns true if aValue is a valid email address.
|
||||
* This is following the HTML5 specification:
|
||||
* http://dev.w3.org/html5/spec/forms.html#valid-e-mail-address
|
||||
*
|
||||
* @param aValue the email address to check.
|
||||
* @result whether the given string is a valid email address.
|
||||
*/
|
||||
static PRBool IsValidEmailAddress(const nsAString& aValue);
|
||||
|
||||
/**
|
||||
* This helper method returns true if aValue is a valid email address list.
|
||||
* Email address list is a list of email address separated by comas (,) which
|
||||
* can be surrounded by space charecters.
|
||||
* This is following the HTML5 specification:
|
||||
* http://dev.w3.org/html5/spec/forms.html#valid-e-mail-address-list
|
||||
*
|
||||
* @param aValue the email address list to check.
|
||||
* @result whether the given string is a valid email address list.
|
||||
*/
|
||||
static PRBool IsValidEmailAddressList(const nsAString& aValue);
|
||||
|
||||
/**
|
||||
* This helper method returns true if the aPattern pattern matches aValue.
|
||||
* aPattern should not contain leading and trailing slashes (/).
|
||||
* The pattern has to match the entire value not just a subset.
|
||||
* aDocument must be a valid pointer (not null).
|
||||
*
|
||||
* This is following the HTML5 specification:
|
||||
* http://dev.w3.org/html5/spec/forms.html#attr-input-pattern
|
||||
*
|
||||
* @param aValue the string to check.
|
||||
* @param aPattern the string defining the pattern.
|
||||
* @param aDocument the owner document of the element.
|
||||
* @result whether the given string is matches the pattern.
|
||||
*/
|
||||
static PRBool IsPatternMatching(nsAString& aValue, nsAString& aPattern,
|
||||
nsIDocument* aDocument);
|
||||
|
||||
// Helper method
|
||||
nsresult SetValueInternal(const nsAString& aValue,
|
||||
PRBool aUserInput,
|
||||
|
@ -322,6 +403,35 @@ protected:
|
|||
*/
|
||||
PRBool NeedToInitializeEditorForEvent(nsEventChainPreVisitor& aVisitor) const;
|
||||
|
||||
/**
|
||||
* Get the value mode of the element, depending of the type.
|
||||
*/
|
||||
ValueModeType GetValueMode() const;
|
||||
|
||||
/**
|
||||
* Get the mutable state of the element.
|
||||
* When the element isn't mutable (immutable), the value or checkedness
|
||||
* should not be changed by the user.
|
||||
*
|
||||
* See: http://dev.w3.org/html5/spec/forms.html#concept-input-mutable
|
||||
*/
|
||||
PRBool IsMutable() const;
|
||||
|
||||
/**
|
||||
* Returns if the readonly attribute applies for the current type.
|
||||
*/
|
||||
PRBool DoesReadOnlyApply() const;
|
||||
|
||||
/**
|
||||
* Returns if the required attribute applies for the current type.
|
||||
*/
|
||||
PRBool DoesRequiredApply() const;
|
||||
|
||||
/**
|
||||
* Returns if the pattern attribute applies for the current type.
|
||||
*/
|
||||
PRBool DoesPatternApply() const;
|
||||
|
||||
void FreeData();
|
||||
nsTextEditorState *GetEditorState() const;
|
||||
|
||||
|
|
|
@ -77,8 +77,7 @@ public:
|
|||
// nsIFormControl
|
||||
NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_LABEL; }
|
||||
NS_IMETHOD Reset();
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement);
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
|
||||
|
||||
NS_IMETHOD Focus();
|
||||
|
||||
|
@ -346,8 +345,7 @@ nsHTMLLabelElement::Reset()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLabelElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement)
|
||||
nsHTMLLabelElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -398,7 +398,7 @@ NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
|
|||
NS_IMPL_URI_ATTR(nsHTMLMediaElement, Src, src)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Controls, controls)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Autoplay, autoplay)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Autobuffer, autobuffer)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLMediaElement, Preload, preload)
|
||||
|
||||
/* readonly attribute nsIDOMHTMLMediaElement mozAutoplayEnabled; */
|
||||
NS_IMETHODIMP nsHTMLMediaElement::GetMozAutoplayEnabled(PRBool *aAutoplayEnabled)
|
||||
|
@ -610,6 +610,13 @@ void nsHTMLMediaElement::SelectResource()
|
|||
if (NS_SUCCEEDED(rv)) {
|
||||
LOG(PR_LOG_DEBUG, ("%p Trying load from src=%s", this, NS_ConvertUTF16toUTF8(src).get()));
|
||||
mIsLoadingFromSrcAttribute = PR_TRUE;
|
||||
if (mPreloadAction == nsHTMLMediaElement::PRELOAD_NONE) {
|
||||
// preload:none media, suspend the load here before we make any
|
||||
// network requests.
|
||||
SuspendLoad(uri);
|
||||
return;
|
||||
}
|
||||
|
||||
rv = LoadResource(uri);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return;
|
||||
|
@ -647,6 +654,13 @@ void nsHTMLMediaElement::LoadFromSourceChildren()
|
|||
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
|
||||
|
||||
if (mPreloadAction == nsHTMLMediaElement::PRELOAD_NONE) {
|
||||
// preload:none media, suspend the load here before we make any
|
||||
// network requests.
|
||||
SuspendLoad(uri);
|
||||
return;
|
||||
}
|
||||
|
||||
rv = LoadResource(uri);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return;
|
||||
|
@ -656,6 +670,111 @@ void nsHTMLMediaElement::LoadFromSourceChildren()
|
|||
NS_NOTREACHED("Execution should not reach here!");
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::SuspendLoad(nsIURI* aURI)
|
||||
{
|
||||
mLoadIsSuspended = PR_TRUE;
|
||||
mPreloadURI = aURI;
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
|
||||
DispatchAsyncProgressEvent(NS_LITERAL_STRING("suspend"));
|
||||
ChangeDelayLoadStatus(PR_FALSE);
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::ResumeLoad(PreloadAction aAction)
|
||||
{
|
||||
NS_ASSERTION(mLoadIsSuspended, "Can only resume preload if halted for one");
|
||||
nsCOMPtr<nsIURI> uri = mPreloadURI;
|
||||
mLoadIsSuspended = PR_FALSE;
|
||||
mPreloadURI = nsnull;
|
||||
mPreloadAction = aAction;
|
||||
ChangeDelayLoadStatus(PR_TRUE);
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
|
||||
if (mIsLoadingFromSrcAttribute) {
|
||||
// We were loading from the element's src attribute.
|
||||
if (NS_FAILED(LoadResource(uri))) {
|
||||
NoSupportedMediaSourceError();
|
||||
}
|
||||
} else {
|
||||
// We were loading from a child <source> element. Try to resume the
|
||||
// load of that child, and if that fails, try the next child.
|
||||
if (NS_FAILED(LoadResource(uri))) {
|
||||
LoadFromSourceChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PRBool IsAutoplayEnabled()
|
||||
{
|
||||
return nsContentUtils::GetBoolPref("media.autoplay.enabled");
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::UpdatePreloadAction()
|
||||
{
|
||||
PreloadAction nextAction = PRELOAD_UNDEFINED;
|
||||
// If autoplay is set, we should always preload data, as we'll need it
|
||||
// to play.
|
||||
if (IsAutoplayEnabled() && HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) {
|
||||
nextAction = nsHTMLMediaElement::PRELOAD_ENOUGH;
|
||||
} else {
|
||||
// Find the appropriate preload action by looking at the attribute.
|
||||
const nsAttrValue* val = mAttrsAndChildren.GetAttr(nsGkAtoms::preload,
|
||||
kNameSpaceID_None);
|
||||
if (!val) {
|
||||
// Attribute is not set. The default is to load metadata.
|
||||
nextAction = nsHTMLMediaElement::PRELOAD_METADATA;
|
||||
} else if (val->Type() == nsAttrValue::eEnum) {
|
||||
PreloadAttrValue attr = static_cast<PreloadAttrValue>(val->GetEnumValue());
|
||||
if (attr == nsHTMLMediaElement::PRELOAD_ATTR_EMPTY ||
|
||||
attr == nsHTMLMediaElement::PRELOAD_ATTR_AUTO)
|
||||
{
|
||||
nextAction = nsHTMLMediaElement::PRELOAD_ENOUGH;
|
||||
} else if (attr == nsHTMLMediaElement::PRELOAD_ATTR_METADATA) {
|
||||
nextAction = nsHTMLMediaElement::PRELOAD_METADATA;
|
||||
} else if (attr == nsHTMLMediaElement::PRELOAD_ATTR_NONE) {
|
||||
nextAction = nsHTMLMediaElement::PRELOAD_NONE;
|
||||
}
|
||||
} else {
|
||||
// There was a value, but it wasn't an enumerated value.
|
||||
// Use the suggested "missing value default" of "metadata".
|
||||
nextAction = nsHTMLMediaElement::PRELOAD_METADATA;
|
||||
}
|
||||
}
|
||||
|
||||
if ((mBegun || mIsRunningSelectResource) && nextAction < mPreloadAction) {
|
||||
// We've started a load or are already downloading, and the preload was
|
||||
// changed to a state where we buffer less. We don't support this case,
|
||||
// so don't change the preload behaviour.
|
||||
return;
|
||||
}
|
||||
|
||||
PRBool wasPreloadNone = mPreloadAction == PRELOAD_NONE;
|
||||
mPreloadAction = nextAction;
|
||||
if (nextAction == nsHTMLMediaElement::PRELOAD_ENOUGH) {
|
||||
if (mLoadIsSuspended) {
|
||||
// Our load was previouly suspended due to the media having preload
|
||||
// value "none". The preload value has changed to preload:auto, so
|
||||
// resume the load.
|
||||
ResumeLoad(PRELOAD_ENOUGH);
|
||||
} else {
|
||||
// Preload as much of the video as we can, i.e. don't suspend after
|
||||
// the first frame.
|
||||
StopSuspendingAfterFirstFrame();
|
||||
}
|
||||
|
||||
} else if (nextAction == nsHTMLMediaElement::PRELOAD_METADATA) {
|
||||
// Ensure that the video can be suspended after first frame.
|
||||
mAllowSuspendAfterFirstFrame = PR_TRUE;
|
||||
if (mLoadIsSuspended) {
|
||||
// Our load was previouly suspended due to the media having preload
|
||||
// value "none". The preload value has changed to preload:metadata, so
|
||||
// resume the load. We'll pause the load again after we've read the
|
||||
// metadata.
|
||||
ResumeLoad(PRELOAD_METADATA);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult nsHTMLMediaElement::LoadResource(nsIURI* aURI)
|
||||
{
|
||||
NS_ASSERTION(mDelayingLoadEvent,
|
||||
|
@ -994,7 +1113,9 @@ nsHTMLMediaElement::nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
|||
mAllowSuspendAfterFirstFrame(PR_TRUE),
|
||||
mHasPlayedOrSeeked(PR_FALSE),
|
||||
mHasSelfReference(PR_FALSE),
|
||||
mShuttingDown(PR_FALSE)
|
||||
mShuttingDown(PR_FALSE),
|
||||
mPreloadAction(PRELOAD_UNDEFINED),
|
||||
mLoadIsSuspended(PR_FALSE)
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
if (!gMediaElementLog) {
|
||||
|
@ -1059,6 +1180,8 @@ NS_IMETHODIMP nsHTMLMediaElement::Play()
|
|||
if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
|
||||
nsresult rv = Load();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else if (mLoadIsSuspended) {
|
||||
ResumeLoad(PRELOAD_ENOUGH);
|
||||
} else if (mDecoder) {
|
||||
if (mDecoder->IsEnded()) {
|
||||
SetCurrentTime(0);
|
||||
|
@ -1099,6 +1222,15 @@ PRBool nsHTMLMediaElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
// Mappings from 'preload' attribute strings to an enumeration.
|
||||
static const nsAttrValue::EnumTable kPreloadTable[] = {
|
||||
{ "", nsHTMLMediaElement::PRELOAD_ATTR_EMPTY },
|
||||
{ "none", nsHTMLMediaElement::PRELOAD_ATTR_NONE },
|
||||
{ "metadata", nsHTMLMediaElement::PRELOAD_ATTR_METADATA },
|
||||
{ "auto", nsHTMLMediaElement::PRELOAD_ATTR_AUTO },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aAttribute == nsGkAtoms::src) {
|
||||
static const char* kWhitespace = " \n\r\t\b";
|
||||
|
@ -1114,6 +1246,9 @@ PRBool nsHTMLMediaElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
else if (ParseImageAttribute(aAttribute, aValue, aResult)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else if (aAttribute == nsGkAtoms::preload) {
|
||||
return aResult.ParseEnumValue(aValue, kPreloadTable, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
|
||||
|
@ -1127,6 +1262,8 @@ nsresult nsHTMLMediaElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
nsresult rv =
|
||||
nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
||||
aNotify);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (aNotify && aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::src) {
|
||||
if (mLoadWaitStatus == WAITING_FOR_SRC_OR_SOURCE) {
|
||||
|
@ -1143,8 +1280,9 @@ nsresult nsHTMLMediaElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
}
|
||||
// This attribute can affect AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
} else if (aName == nsGkAtoms::autobuffer) {
|
||||
StopSuspendingAfterFirstFrame();
|
||||
UpdatePreloadAction();
|
||||
} else if (aName == nsGkAtoms::preload) {
|
||||
UpdatePreloadAction();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1155,23 +1293,21 @@ nsresult nsHTMLMediaElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttr,
|
|||
PRBool aNotify)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttr, aNotify);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (aNotify && aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aAttr == nsGkAtoms::autoplay) {
|
||||
// This attribute can affect AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
UpdatePreloadAction();
|
||||
} else if (aAttr == nsGkAtoms::preload) {
|
||||
UpdatePreloadAction();
|
||||
}
|
||||
// We perhaps should stop loading if 'autobuffer' is being removed,
|
||||
// and we're buffering only because of 'autobuffer', but why bother?
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static PRBool IsAutoplayEnabled()
|
||||
{
|
||||
return nsContentUtils::GetBoolPref("media.autoplay.enabled");
|
||||
}
|
||||
|
||||
nsresult nsHTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
|
@ -1180,6 +1316,9 @@ nsresult nsHTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aPar
|
|||
mIsBindingToTree = PR_TRUE;
|
||||
mAutoplayEnabled =
|
||||
IsAutoplayEnabled() && (!aDocument || !aDocument->IsStaticDocument());
|
||||
// The preload action depends on the value of the autoplay attribute.
|
||||
// It's value may have changed, so update it.
|
||||
UpdatePreloadAction();
|
||||
}
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument,
|
||||
aParent,
|
||||
|
@ -1641,7 +1780,7 @@ void nsHTMLMediaElement::FirstFrameLoaded(PRBool aResourceFullyLoaded)
|
|||
if (mDecoder && mAllowSuspendAfterFirstFrame && mPaused &&
|
||||
!aResourceFullyLoaded &&
|
||||
!HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
|
||||
!HasAttr(kNameSpaceID_None, nsGkAtoms::autobuffer)) {
|
||||
mPreloadAction == nsHTMLMediaElement::PRELOAD_METADATA) {
|
||||
mSuspendedAfterFirstFrame = PR_TRUE;
|
||||
mDecoder->Suspend();
|
||||
}
|
||||
|
@ -1944,6 +2083,7 @@ nsresult nsHTMLMediaElement::DoneAddingChildren(PRBool aHaveNotified)
|
|||
if (!mIsDoneAddingChildren) {
|
||||
mIsDoneAddingChildren = PR_TRUE;
|
||||
|
||||
UpdatePreloadAction();
|
||||
if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
|
||||
QueueSelectResourceTask();
|
||||
}
|
||||
|
|
|
@ -104,8 +104,7 @@ public:
|
|||
}
|
||||
|
||||
NS_IMETHOD Reset();
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission *aFormSubmission,
|
||||
nsIContent *aSubmitElement);
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission *aFormSubmission);
|
||||
|
||||
virtual nsresult DoneAddingChildren(PRBool aHaveNotified);
|
||||
virtual PRBool IsDoneAddingChildren();
|
||||
|
@ -321,8 +320,7 @@ nsHTMLObjectElement::Reset()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLObjectElement::SubmitNamesValues(nsFormSubmission *aFormSubmission,
|
||||
nsIContent *aSubmitElement)
|
||||
nsHTMLObjectElement::SubmitNamesValues(nsFormSubmission *aFormSubmission)
|
||||
{
|
||||
nsAutoString name;
|
||||
if (!GetAttr(kNameSpaceID_None, nsGkAtoms::name, name)) {
|
||||
|
|
|
@ -68,8 +68,7 @@ public:
|
|||
// nsIFormControl
|
||||
NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_OUTPUT; }
|
||||
NS_IMETHOD Reset();
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement);
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
|
||||
|
||||
nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const;
|
||||
|
||||
|
@ -148,8 +147,7 @@ nsHTMLOutputElement::Reset()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLOutputElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement)
|
||||
nsHTMLOutputElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
|
||||
{
|
||||
// The output element is not submittable.
|
||||
return NS_OK;
|
||||
|
|
|
@ -194,6 +194,9 @@ NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLSelectElement)
|
|||
|
||||
NS_IMPL_ELEMENT_CLONE(nsHTMLSelectElement)
|
||||
|
||||
// nsConstraintValidation
|
||||
NS_IMPL_NSCONSTRAINTVALIDATION(nsHTMLSelectElement)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLSelectElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
||||
{
|
||||
|
@ -1449,6 +1452,12 @@ nsHTMLSelectElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||
return nsGenericHTMLFormElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsHTMLSelectElement::IntrinsicState() const
|
||||
{
|
||||
return NS_EVENT_STATE_OPTIONAL | nsGenericHTMLFormElement::IntrinsicState();
|
||||
}
|
||||
|
||||
// nsIFormControl
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1596,8 +1605,7 @@ nsHTMLSelectElement::Reset()
|
|||
static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLSelectElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement)
|
||||
nsHTMLSelectElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -1747,7 +1755,6 @@ nsHTMLSelectElement::VerifyOptionsArray()
|
|||
VerifyOptionsRecurse(this, aIndex, mOptions);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsISelectControlFrame.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIHTMLCollection.h"
|
||||
#include "nsConstraintValidation.h"
|
||||
|
||||
// PresState
|
||||
#include "nsXPCOM.h"
|
||||
|
@ -236,7 +237,8 @@ private:
|
|||
*/
|
||||
class nsHTMLSelectElement : public nsGenericHTMLFormElement,
|
||||
public nsIDOMHTMLSelectElement,
|
||||
public nsISelectElement
|
||||
public nsISelectElement,
|
||||
public nsConstraintValidation
|
||||
{
|
||||
public:
|
||||
nsHTMLSelectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
|
@ -269,11 +271,12 @@ public:
|
|||
// Overriden nsIFormControl methods
|
||||
NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_SELECT; }
|
||||
NS_IMETHOD Reset();
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement);
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
|
||||
NS_IMETHOD SaveState();
|
||||
virtual PRBool RestoreState(nsPresState* aState);
|
||||
|
||||
PRInt32 IntrinsicState() const;
|
||||
|
||||
// nsISelectElement
|
||||
NS_DECL_NSISELECTELEMENT
|
||||
|
||||
|
|
|
@ -159,7 +159,6 @@ NS_IMPL_RELEASE_INHERITED(nsHTMLSharedElement, nsGenericElement)
|
|||
DOMCI_DATA(HTMLParamElement, nsHTMLSharedElement)
|
||||
DOMCI_DATA(HTMLIsIndexElement, nsHTMLSharedElement)
|
||||
DOMCI_DATA(HTMLBaseElement, nsHTMLSharedElement)
|
||||
DOMCI_DATA(HTMLSpacerElement, nsHTMLSharedElement)
|
||||
DOMCI_DATA(HTMLDirectoryElement, nsHTMLSharedElement)
|
||||
DOMCI_DATA(HTMLMenuElement, nsHTMLSharedElement)
|
||||
DOMCI_DATA(HTMLQuoteElement, nsHTMLSharedElement)
|
||||
|
@ -178,9 +177,6 @@ nsHTMLSharedElement::GetClassInfoInternal()
|
|||
if (mNodeInfo->Equals(nsGkAtoms::base)) {
|
||||
return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLBaseElement_id);
|
||||
}
|
||||
if (mNodeInfo->Equals(nsGkAtoms::spacer)) {
|
||||
return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLSpacerElement_id);
|
||||
}
|
||||
if (mNodeInfo->Equals(nsGkAtoms::dir)) {
|
||||
return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLDirectoryElement_id);
|
||||
}
|
||||
|
@ -278,27 +274,14 @@ nsHTMLSharedElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (mNodeInfo->Equals(nsGkAtoms::spacer)) {
|
||||
if (aAttribute == nsGkAtoms::size) {
|
||||
return aResult.ParseIntWithBounds(aValue, 0);
|
||||
}
|
||||
if (aAttribute == nsGkAtoms::align) {
|
||||
return ParseAlignValue(aValue, aResult);
|
||||
}
|
||||
if (aAttribute == nsGkAtoms::width ||
|
||||
aAttribute == nsGkAtoms::height) {
|
||||
return aResult.ParseSpecialIntValue(aValue, PR_TRUE);
|
||||
}
|
||||
if (aNamespaceID == kNameSpaceID_None &&
|
||||
(mNodeInfo->Equals(nsGkAtoms::dir) ||
|
||||
mNodeInfo->Equals(nsGkAtoms::menu))) {
|
||||
if (aAttribute == nsGkAtoms::type) {
|
||||
return aResult.ParseEnumValue(aValue, kListTypeTable, PR_FALSE);
|
||||
}
|
||||
else if (mNodeInfo->Equals(nsGkAtoms::dir) ||
|
||||
mNodeInfo->Equals(nsGkAtoms::menu)) {
|
||||
if (aAttribute == nsGkAtoms::type) {
|
||||
return aResult.ParseEnumValue(aValue, kListTypeTable, PR_FALSE);
|
||||
}
|
||||
if (aAttribute == nsGkAtoms::start) {
|
||||
return aResult.ParseIntWithBounds(aValue, 1);
|
||||
}
|
||||
if (aAttribute == nsGkAtoms::start) {
|
||||
return aResult.ParseIntWithBounds(aValue, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,98 +289,6 @@ nsHTMLSharedElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
aResult);
|
||||
}
|
||||
|
||||
// spacer element code
|
||||
|
||||
static void
|
||||
SpacerMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
nsRuleData* aData)
|
||||
{
|
||||
nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aData);
|
||||
|
||||
if (aData->mSIDs & (NS_STYLE_INHERIT_BIT(Position) |
|
||||
NS_STYLE_INHERIT_BIT(Display))) {
|
||||
PRBool typeIsBlock = PR_FALSE;
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::type);
|
||||
if (value && value->Type() == nsAttrValue::eString) {
|
||||
const nsString& tmp(value->GetStringValue());
|
||||
if (tmp.LowerCaseEqualsLiteral("line") ||
|
||||
tmp.LowerCaseEqualsLiteral("vert") ||
|
||||
tmp.LowerCaseEqualsLiteral("vertical") ||
|
||||
tmp.LowerCaseEqualsLiteral("block")) {
|
||||
// This is not strictly 100% compatible: if the spacer is given
|
||||
// a width of zero then it is basically ignored.
|
||||
typeIsBlock = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)) {
|
||||
if (typeIsBlock) {
|
||||
// width: value
|
||||
if (aData->mPositionData->mWidth.GetUnit() == eCSSUnit_Null) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
aData->mPositionData->
|
||||
mWidth.SetFloatValue((float)value->GetIntegerValue(),
|
||||
eCSSUnit_Pixel);
|
||||
} else if (value && value->Type() == nsAttrValue::ePercent) {
|
||||
aData->mPositionData->
|
||||
mWidth.SetPercentValue(value->GetPercentValue());
|
||||
}
|
||||
}
|
||||
|
||||
// height: value
|
||||
if (aData->mPositionData->mHeight.GetUnit() == eCSSUnit_Null) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
aData->mPositionData->
|
||||
mHeight.SetFloatValue((float)value->GetIntegerValue(),
|
||||
eCSSUnit_Pixel);
|
||||
} else if (value && value->Type() == nsAttrValue::ePercent) {
|
||||
aData->mPositionData->
|
||||
mHeight.SetPercentValue(value->GetPercentValue());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// size: value
|
||||
if (aData->mPositionData->mWidth.GetUnit() == eCSSUnit_Null) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::size);
|
||||
if (value && value->Type() == nsAttrValue::eInteger)
|
||||
aData->mPositionData->
|
||||
mWidth.SetFloatValue((float)value->GetIntegerValue(),
|
||||
eCSSUnit_Pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Display)) {
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
|
||||
if (value && value->Type() == nsAttrValue::eEnum) {
|
||||
PRInt32 align = value->GetEnumValue();
|
||||
if (aData->mDisplayData->mFloat.GetUnit() == eCSSUnit_Null) {
|
||||
if (align == NS_STYLE_TEXT_ALIGN_LEFT)
|
||||
aData->mDisplayData->mFloat.SetIntValue(NS_STYLE_FLOAT_LEFT,
|
||||
eCSSUnit_Enumerated);
|
||||
else if (align == NS_STYLE_TEXT_ALIGN_RIGHT)
|
||||
aData->mDisplayData->mFloat.SetIntValue(NS_STYLE_FLOAT_RIGHT,
|
||||
eCSSUnit_Enumerated);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeIsBlock) {
|
||||
if (aData->mDisplayData->mDisplay.GetUnit() == eCSSUnit_Null) {
|
||||
aData->mDisplayData->mDisplay.SetIntValue(NS_STYLE_DISPLAY_BLOCK,
|
||||
eCSSUnit_Enumerated);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Any new structs that don't need typeIsBlock should go outside
|
||||
// the code that calculates it.
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
|
||||
}
|
||||
|
||||
static void
|
||||
DirectoryMenuMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
nsRuleData* aData)
|
||||
|
@ -422,25 +313,6 @@ DirectoryMenuMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
|||
NS_IMETHODIMP_(PRBool)
|
||||
nsHTMLSharedElement::IsAttributeMapped(const nsIAtom* aAttribute) const
|
||||
{
|
||||
if (mNodeInfo->Equals(nsGkAtoms::spacer)) {
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
// XXXldb This is just wrong.
|
||||
{ &nsGkAtoms::usemap },
|
||||
{ &nsGkAtoms::ismap },
|
||||
{ &nsGkAtoms::align },
|
||||
{ nsnull }
|
||||
};
|
||||
|
||||
static const MappedAttributeEntry* const map[] = {
|
||||
attributes,
|
||||
sCommonAttributeMap,
|
||||
sImageMarginSizeAttributeMap,
|
||||
sImageBorderAttributeMap,
|
||||
};
|
||||
|
||||
return FindAttributeDependence(aAttribute, map, NS_ARRAY_LENGTH(map));
|
||||
}
|
||||
|
||||
if (mNodeInfo->Equals(nsGkAtoms::dir)) {
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::type },
|
||||
|
@ -598,11 +470,7 @@ nsHTMLSharedElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
|||
nsMapRuleToAttributesFunc
|
||||
nsHTMLSharedElement::GetAttributeMappingFunction() const
|
||||
{
|
||||
if (mNodeInfo->Equals(nsGkAtoms::spacer)) {
|
||||
return &SpacerMapAttributesIntoRule;
|
||||
}
|
||||
else if (mNodeInfo->Equals(nsGkAtoms::dir) ||
|
||||
mNodeInfo->Equals(nsGkAtoms::menu)) {
|
||||
if (mNodeInfo->Equals(nsGkAtoms::dir) || mNodeInfo->Equals(nsGkAtoms::menu)) {
|
||||
return &DirectoryMenuMapAttributesIntoRule;
|
||||
}
|
||||
|
||||
|
|
|
@ -1061,23 +1061,22 @@ MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
|||
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(TableBorder)) {
|
||||
const nsStyleDisplay* readDisplay = aData->mStyleContext->GetStyleDisplay();
|
||||
if (readDisplay->mDisplay != NS_STYLE_DISPLAY_TABLE_CELL) {
|
||||
// cellspacing
|
||||
// cellspacing
|
||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::cellspacing);
|
||||
if (value && value->Type() == nsAttrValue::eInteger) {
|
||||
if (aData->mTableData->mBorderSpacing.mXValue.GetUnit() == eCSSUnit_Null)
|
||||
aData->mTableData->mBorderSpacing.mXValue.SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
|
||||
if (aData->mTableData->mBorderSpacing.mYValue.GetUnit() == eCSSUnit_Null)
|
||||
aData->mTableData->mBorderSpacing.mYValue.SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
|
||||
if (aData->mTableData->mBorderSpacing.GetUnit() == eCSSUnit_Null)
|
||||
aData->mTableData->mBorderSpacing.
|
||||
SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
|
||||
}
|
||||
else if (value && value->Type() == nsAttrValue::ePercent && eCompatibility_NavQuirks == mode) {
|
||||
else if (value && value->Type() == nsAttrValue::ePercent &&
|
||||
eCompatibility_NavQuirks == mode) {
|
||||
// in quirks mode, treat a % cellspacing value a pixel value.
|
||||
if (aData->mTableData->mBorderSpacing.mXValue.GetUnit() == eCSSUnit_Null)
|
||||
aData->mTableData->mBorderSpacing.mXValue.SetFloatValue(100.0f * value->GetPercentValue(), eCSSUnit_Pixel);
|
||||
if (aData->mTableData->mBorderSpacing.mYValue.GetUnit() == eCSSUnit_Null)
|
||||
aData->mTableData->mBorderSpacing.mYValue.SetFloatValue(100.0f * value->GetPercentValue(), eCSSUnit_Pixel);
|
||||
if (aData->mTableData->mBorderSpacing.GetUnit() == eCSSUnit_Null)
|
||||
aData->mTableData->mBorderSpacing.
|
||||
SetFloatValue(100.0f * value->GetPercentValue(), eCSSUnit_Pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Table)) {
|
||||
const nsStyleDisplay* readDisplay = aData->mStyleContext->GetStyleDisplay();
|
||||
if (readDisplay->mDisplay != NS_STYLE_DISPLAY_TABLE_CELL) {
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
#include "mozAutoDocUpdate.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsConstraintValidation.h"
|
||||
|
||||
#include "nsTextEditorState.h"
|
||||
|
||||
|
@ -89,7 +90,8 @@ class nsHTMLTextAreaElement : public nsGenericHTMLFormElement,
|
|||
public nsIDOMNSHTMLTextAreaElement,
|
||||
public nsITextControlElement,
|
||||
public nsIDOMNSEditableElement,
|
||||
public nsStubMutationObserver
|
||||
public nsStubMutationObserver,
|
||||
public nsConstraintValidation
|
||||
{
|
||||
public:
|
||||
nsHTMLTextAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
|
@ -123,11 +125,12 @@ public:
|
|||
// nsIFormControl
|
||||
NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_TEXTAREA; }
|
||||
NS_IMETHOD Reset();
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement);
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
|
||||
NS_IMETHOD SaveState();
|
||||
virtual PRBool RestoreState(nsPresState* aState);
|
||||
|
||||
virtual PRInt32 IntrinsicState() const;
|
||||
|
||||
// nsITextControlElemet
|
||||
NS_IMETHOD SetValueChanged(PRBool aValueChanged);
|
||||
NS_IMETHOD_(PRBool) IsSingleLineTextControl() const;
|
||||
|
@ -196,6 +199,14 @@ public:
|
|||
nsGenericHTMLFormElement)
|
||||
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
// nsConstraintValidation
|
||||
PRBool IsTooLong();
|
||||
PRBool IsValueMissing();
|
||||
PRBool IsBarredFromConstraintValidation();
|
||||
nsresult GetValidationMessage(nsAString& aValidationMessage,
|
||||
ValidationMessageType aType);
|
||||
|
||||
protected:
|
||||
using nsGenericHTMLFormElement::IsSingleLineTextControl; // get rid of the compiler warning
|
||||
|
||||
|
@ -242,6 +253,11 @@ protected:
|
|||
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom *aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
|
||||
/**
|
||||
* Get the mutable state of the element.
|
||||
*/
|
||||
PRBool IsMutable() const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -297,6 +313,9 @@ NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLTextAreaElement)
|
|||
|
||||
NS_IMPL_ELEMENT_CLONE(nsHTMLTextAreaElement)
|
||||
|
||||
// nsConstraintValidation
|
||||
NS_IMPL_NSCONSTRAINTVALIDATION(nsHTMLTextAreaElement)
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLTextAreaElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
||||
|
@ -397,6 +416,7 @@ NS_IMPL_BOOL_ATTR(nsHTMLTextAreaElement, Disabled, disabled)
|
|||
NS_IMPL_NON_NEGATIVE_INT_ATTR(nsHTMLTextAreaElement, MaxLength, maxlength)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLTextAreaElement, Name, name)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLTextAreaElement, ReadOnly, readonly)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLTextAreaElement, Required, required)
|
||||
NS_IMPL_INT_ATTR(nsHTMLTextAreaElement, Rows, rows)
|
||||
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLTextAreaElement, TabIndex, tabindex, 0)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLTextAreaElement, Wrap, wrap)
|
||||
|
@ -837,8 +857,7 @@ nsHTMLTextAreaElement::Reset()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLTextAreaElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
|
||||
nsIContent* aSubmitElement)
|
||||
nsHTMLTextAreaElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -935,7 +954,19 @@ nsHTMLTextAreaElement::RestoreState(nsPresState* aState)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsHTMLTextAreaElement::IntrinsicState() const
|
||||
{
|
||||
PRInt32 state = nsGenericHTMLFormElement::IntrinsicState();
|
||||
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
|
||||
state |= NS_EVENT_STATE_REQUIRED;
|
||||
} else {
|
||||
state |= NS_EVENT_STATE_OPTIONAL;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLTextAreaElement::BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
|
@ -1032,6 +1063,96 @@ nsHTMLTextAreaElement::CopyInnerTo(nsGenericElement* aDest) const
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLTextAreaElement::IsMutable() const
|
||||
{
|
||||
return (!HasAttr(kNameSpaceID_None, nsGkAtoms::readonly) &&
|
||||
!HasAttr(kNameSpaceID_None, nsGkAtoms::disabled));
|
||||
}
|
||||
|
||||
// nsConstraintValidation
|
||||
|
||||
PRBool
|
||||
nsHTMLTextAreaElement::IsTooLong()
|
||||
{
|
||||
if (!mValueChanged) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRInt32 maxLength = -1;
|
||||
PRInt32 textLength = -1;
|
||||
|
||||
GetMaxLength(&maxLength);
|
||||
GetTextLength(&textLength);
|
||||
|
||||
return (maxLength >= 0) && (textLength > maxLength);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLTextAreaElement::IsValueMissing()
|
||||
{
|
||||
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::required) || !IsMutable()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsAutoString value;
|
||||
nsresult rv = GetValue(value);
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
|
||||
return value.IsEmpty();
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLTextAreaElement::IsBarredFromConstraintValidation()
|
||||
{
|
||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLTextAreaElement::GetValidationMessage(nsAString& aValidationMessage,
|
||||
ValidationMessageType aType)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
switch (aType)
|
||||
{
|
||||
case VALIDATION_MESSAGE_TOO_LONG:
|
||||
{
|
||||
nsXPIDLString message;
|
||||
PRInt32 maxLength = -1;
|
||||
PRInt32 textLength = -1;
|
||||
nsAutoString strMaxLength;
|
||||
nsAutoString strTextLength;
|
||||
|
||||
GetMaxLength(&maxLength);
|
||||
GetTextLength(&textLength);
|
||||
|
||||
strMaxLength.AppendInt(maxLength);
|
||||
strTextLength.AppendInt(textLength);
|
||||
|
||||
const PRUnichar* params[] = { strTextLength.get(), strMaxLength.get() };
|
||||
rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"ElementSuffersFromBeingTooLong",
|
||||
params, 2, message);
|
||||
aValidationMessage = message;
|
||||
}
|
||||
break;
|
||||
case VALIDATION_MESSAGE_VALUE_MISSING:
|
||||
{
|
||||
nsXPIDLString message;
|
||||
rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"TextElementSuffersFromBeingMissing",
|
||||
message);
|
||||
aValidationMessage = message;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rv = nsConstraintValidation::GetValidationMessage(aValidationMessage, aType);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsHTMLTextAreaElement::IsSingleLineTextControl() const
|
||||
{
|
||||
|
|
|
@ -191,6 +191,17 @@ _TEST_FILES = \
|
|||
test_bug573969.html \
|
||||
test_bug549475.html \
|
||||
test_bug585508.html \
|
||||
test_bug345624-1.html \
|
||||
test_bug345624-2.html \
|
||||
test_bug561640.html \
|
||||
test_bug345822.html \
|
||||
test_bug555559.html \
|
||||
test_bug344615.html \
|
||||
test_bug345512.html \
|
||||
test_bug566064.html \
|
||||
test_bug566160.html \
|
||||
test_bug582412-1.html \
|
||||
test_bug582412-2.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=344615
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 344615</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=344615">Mozilla Bug 344615</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<input type='url' id='i' oninvalid='invalidEventHandler(event);'>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 344615 **/
|
||||
|
||||
// More checks are done in test_bug551670.html.
|
||||
|
||||
var gInvalid = false;
|
||||
|
||||
function invalidEventHandler(e)
|
||||
{
|
||||
is(e.type, "invalid", "Invalid event type should be invalid");
|
||||
gInvalid = true;
|
||||
}
|
||||
|
||||
function checkValidURL(element)
|
||||
{
|
||||
gInvalid = false;
|
||||
ok(!element.validity.typeMismatch,
|
||||
"Element should not suffer from type mismatch");
|
||||
ok(element.validity.valid, "Element should be valid");
|
||||
ok(element.checkValidity(), "Element should be valid");
|
||||
ok(!gInvalid, "The invalid event should not have been thrown");
|
||||
is(element.validationMessage, '',
|
||||
"Validation message should be the empty string");
|
||||
}
|
||||
|
||||
function checkInvalidURL(element)
|
||||
{
|
||||
gInvalid = false;
|
||||
ok(element.validity.typeMismatch,
|
||||
"Element should suffer from type mismatch");
|
||||
ok(!element.validity.valid, "Element should not be valid");
|
||||
ok(!element.checkValidity(), "Element should not be valid");
|
||||
ok(gInvalid, "The invalid event should have been thrown");
|
||||
is(element.validationMessage, "The entered URL is not valid.",
|
||||
"Validation message should be related to invalid URL");
|
||||
}
|
||||
|
||||
var url = document.getElementById('i');
|
||||
is(url.type, 'url', "url state should be recognized");
|
||||
|
||||
// The empty string should not be considered as invalid.
|
||||
url.value = '';
|
||||
checkValidURL(url);
|
||||
|
||||
// We are only testing obviously (in)valid URI's because the function used
|
||||
// to check if an URI is valid is not specific to this functionality.
|
||||
url.value = 'foo';
|
||||
checkInvalidURL(url);
|
||||
|
||||
url.value = 'http://mozilla.com/';
|
||||
checkValidURL(url);
|
||||
|
||||
url.value = 'http://mozil\nla\r.com/';
|
||||
checkValidURL(url);
|
||||
|
||||
url.value = ' http://mozilla.com/ ';
|
||||
checkValidURL(url);
|
||||
|
||||
url.value = '\r http://mozilla.com/ \n';
|
||||
checkValidURL(url);
|
||||
|
||||
url.value = 'file:///usr/bin/tulip';
|
||||
checkValidURL(url);
|
||||
|
||||
url.value = '../../bar.html';
|
||||
checkInvalidURL(url);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,300 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=345512
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 345512</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=345512">Mozilla Bug 345512</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<input id='i' pattern="tulip" oninvalid="invalidEventHandler(event);">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 345512 **/
|
||||
|
||||
var gInvalid = false;
|
||||
|
||||
function invalidEventHandler(e)
|
||||
{
|
||||
is(e.type, "invalid", "Invalid event type should be invalid");
|
||||
gInvalid = true;
|
||||
}
|
||||
|
||||
function checkPatternAttribute(element)
|
||||
{
|
||||
ok('pattern' in element, "Element should have the pattern attribute");
|
||||
|
||||
is(element.pattern, "tulip",
|
||||
"pattern IDL attribute value should be 'tulip'");
|
||||
is(element.getAttribute('pattern'), "tulip",
|
||||
"pattern content attribute value should be 'tulip'");
|
||||
|
||||
element.pattern = "foo";
|
||||
is(element.pattern, "foo",
|
||||
"pattern IDL attribute value should be 'foo'");
|
||||
is(element.getAttribute('pattern'), "foo",
|
||||
"pattern content attribute value should be 'foo'");
|
||||
|
||||
element.removeAttribute('pattern');
|
||||
ok(!element.pattern,
|
||||
"Element pattern attribute shouldn't be specified");
|
||||
is(element.getAttribute('pattern'), null,
|
||||
"Element pattern attribute shouldn't be specified");
|
||||
|
||||
element.setAttribute("pattern", "bar");
|
||||
is(element.pattern, "bar",
|
||||
"pattern IDL attribute value should be 'bar'");
|
||||
is(element.getAttribute('pattern'), "bar",
|
||||
"pattern content attribute value should be 'bar'");
|
||||
}
|
||||
|
||||
function completeValidityCheck(element, alwaysValid)
|
||||
{
|
||||
if (element.type == 'file') {
|
||||
// Need privileges to set a filename with .value.
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
}
|
||||
|
||||
// Check when pattern matches.
|
||||
if (element.type == 'email') {
|
||||
element.pattern = ".*@bar.com";
|
||||
element.value = "foo@bar.com";
|
||||
} else if (element.type == 'url') {
|
||||
element.pattern = "http://.*\\.com$";
|
||||
element.value = "http://mozilla.com";
|
||||
} else {
|
||||
element.pattern = "foo";
|
||||
element.value = "foo";
|
||||
}
|
||||
|
||||
checkValidPattern(element, true);
|
||||
|
||||
// Check when pattern does not match.
|
||||
|
||||
if (element.type == 'email') {
|
||||
element.pattern = ".*@bar.com";
|
||||
element.value = "foo@foo.com";
|
||||
} else if (element.type == 'url') {
|
||||
element.pattern = "http://.*\\.com$";
|
||||
element.value = "http://mozilla.org";
|
||||
} else {
|
||||
element.pattern = "foo";
|
||||
element.value = "bar";
|
||||
}
|
||||
|
||||
if (!alwaysValid) {
|
||||
checkInvalidPattern(element, true);
|
||||
} else {
|
||||
checkValidPattern(element, true);
|
||||
}
|
||||
}
|
||||
|
||||
function checkValidPattern(element, completeCheck)
|
||||
{
|
||||
if (completeCheck) {
|
||||
gInvalid = false;
|
||||
|
||||
ok(!element.validity.patternMismatch,
|
||||
"Element should not suffer from pattern mismatch");
|
||||
ok(element.validity.valid, "Element should be valid");
|
||||
ok(element.checkValidity(), "Element should be valid");
|
||||
ok(!gInvalid, "Invalid event shouldn't have been thrown");
|
||||
is(element.validationMessage, '',
|
||||
"Validation message should be the empty string");
|
||||
} else {
|
||||
ok(!element.validity.patternMismatch,
|
||||
"Element should not suffer from pattern mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
function checkInvalidPattern(element, completeCheck)
|
||||
{
|
||||
if (completeCheck) {
|
||||
gInvalid = false;
|
||||
|
||||
ok(element.validity.patternMismatch,
|
||||
"Element should suffer from pattern mismatch");
|
||||
ok(!element.validity.valid, "Element should not be valid");
|
||||
ok(!element.checkValidity(), "Element should not be valid");
|
||||
ok(gInvalid, "Invalid event should have been thrown");
|
||||
is(element.validationMessage,
|
||||
"The field value is not in the requested format.",
|
||||
"Validation message is not valid");
|
||||
} else {
|
||||
ok(element.validity.patternMismatch,
|
||||
"Element should suffer from pattern mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
function checkPatternValidity(element)
|
||||
{
|
||||
element.pattern = "foo";
|
||||
|
||||
element.value = '';
|
||||
checkValidPattern(element);
|
||||
|
||||
element.value = "foo";
|
||||
checkValidPattern(element);
|
||||
|
||||
element.value = "bar";
|
||||
checkInvalidPattern(element);
|
||||
|
||||
element.value = "foobar";
|
||||
checkInvalidPattern(element);
|
||||
|
||||
element.value = "foofoo";
|
||||
checkInvalidPattern(element);
|
||||
|
||||
element.pattern = "foo\"bar";
|
||||
element.value = "foo\"bar";
|
||||
checkValidPattern(element);
|
||||
|
||||
element.value = 'foo"bar';
|
||||
checkValidPattern(element);
|
||||
|
||||
element.pattern = "foo'bar";
|
||||
element.value = "foo\'bar";
|
||||
checkValidPattern(element);
|
||||
|
||||
element.pattern = "foo\\(bar";
|
||||
element.value = "foo(bar";
|
||||
checkValidPattern(element);
|
||||
|
||||
element.value = "foo";
|
||||
checkInvalidPattern(element);
|
||||
|
||||
element.pattern = "foo\\)bar";
|
||||
element.value = "foo)bar";
|
||||
checkValidPattern(element);
|
||||
|
||||
element.value = "foo";
|
||||
checkInvalidPattern(element);
|
||||
|
||||
// We need '\\\\' because '\\' will produce '\\' and we want to escape the '\'
|
||||
// for the regexp.
|
||||
element.pattern = "foo\\\\bar";
|
||||
element.value = "foo\\bar";
|
||||
checkValidPattern(element);
|
||||
|
||||
// The same way, we want to escape the ' in the pattern.
|
||||
element.pattern = "foo\\'bar";
|
||||
element.value = "foo'bar";
|
||||
checkValidPattern(element);
|
||||
|
||||
// Check for 'i' flag disabled. Should be case sensitive.
|
||||
element.value = "Foo";
|
||||
checkInvalidPattern(element);
|
||||
|
||||
// We can't check for the 'g' flag because we only test, we don't execute.
|
||||
// We can't check for the 'm' flag because .value shouldn't contain line breaks.
|
||||
|
||||
// We should check the pattern attribute do not pollute |RegExp.lastParen|.
|
||||
is(RegExp.lastParen, "", "RegExp.lastParen should be the empty string");
|
||||
|
||||
element.pattern = "(foo)";
|
||||
element.value = "foo";
|
||||
checkValidPattern(element);
|
||||
is(RegExp.lastParen, "", "RegExp.lastParen should be the empty string");
|
||||
|
||||
// That may sound weird but the empty string is a valid pattern value.
|
||||
element.pattern = "";
|
||||
element.value = "";
|
||||
checkValidPattern(element);
|
||||
|
||||
element.value = "foo";
|
||||
checkInvalidPattern(element);
|
||||
|
||||
// Checking some complex patterns. As we are using js regexp mechanism, these
|
||||
// tests doesn't aim to test the regexp mechanism.
|
||||
element.pattern = "\\d{2}\\s\\d{2}\\s\\d{4}"
|
||||
element.value = "01 01 2010"
|
||||
checkValidPattern(element);
|
||||
|
||||
element.value = "01/01/2010"
|
||||
checkInvalidPattern(element);
|
||||
|
||||
element.pattern = "[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z_+])*@([0-9a-zA-Z][-\\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9}";
|
||||
element.value = "foo@bar.com";
|
||||
checkValidPattern(element);
|
||||
|
||||
element.value = "...@bar.com";
|
||||
checkInvalidPattern(element);
|
||||
|
||||
element.pattern = "^(?:\\w{3,})$";
|
||||
element.value = "foo";
|
||||
checkValidPattern(element);
|
||||
|
||||
element.value = "f";
|
||||
checkInvalidPattern(element);
|
||||
|
||||
// If @title is specified, it should be added in the validation message.
|
||||
if (element.type == 'email') {
|
||||
element.pattern = "foo@bar.com"
|
||||
element.value = "bar@foo.com";
|
||||
} else if (element.type == 'url') {
|
||||
element.pattern = "http://mozilla.com";
|
||||
element.value = "http://mozilla.org";
|
||||
} else {
|
||||
element.pattern = "foo";
|
||||
element.value = "bar";
|
||||
}
|
||||
element.title = "This is an explanation of the regexp.";
|
||||
is(element.validationMessage,
|
||||
"The field value is not in the requested format. " + element.title,
|
||||
"Validation message is not valid");
|
||||
element.title = "";
|
||||
is(element.validationMessage,
|
||||
"The field value is not in the requested format.",
|
||||
"Validation message is not valid");
|
||||
|
||||
element.pattern = "foo";
|
||||
if (element.type == 'email') {
|
||||
element.value = "bar@foo.com";
|
||||
} else if (element.type == 'url') {
|
||||
element.value = "http://mozilla.org";
|
||||
} else {
|
||||
element.value = "bar";
|
||||
}
|
||||
checkInvalidPattern(element);
|
||||
|
||||
element.removeAttribute('pattern');
|
||||
checkValidPattern(element, true);
|
||||
}
|
||||
|
||||
var input = document.getElementById('i');
|
||||
|
||||
// All input types should have the pattern attribute.
|
||||
checkPatternAttribute(input);
|
||||
|
||||
// |validTypes| are the types which accept @pattern
|
||||
// and |invalidTypes| are the ones which do not accept it.
|
||||
var validTypes = Array('text', 'password', 'search', 'telephone', 'email', 'url');
|
||||
var invalidTypes = Array('hidden', 'checkbox', 'radio', 'file', 'submit',
|
||||
'image', 'reset', 'button');
|
||||
// TODO: 'datetime', 'date', 'month', 'week', 'time', 'datetime-local',
|
||||
// 'number', 'range', ande 'color' do not accept the @pattern too but are
|
||||
// not implemented yet.
|
||||
|
||||
for each (type in validTypes) {
|
||||
input.type = type;
|
||||
completeValidityCheck(input, false);
|
||||
checkPatternValidity(input);
|
||||
}
|
||||
|
||||
for each (type in invalidTypes) {
|
||||
input.type = type;
|
||||
completeValidityCheck(input, true);
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,242 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=345624
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 345624</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=345624">Mozilla Bug 345624</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<fieldset id='f'></fieldset>
|
||||
<input id='i' oninvalid="invalidEventHandler(event);">
|
||||
<button id='b' oninvalid="invalidEventHandler(event);"></button>
|
||||
<select id='s' oninvalid="invalidEventHandler(event);"></select>
|
||||
<textarea id='t' oninvalid="invalidEventHandler(event);"></textarea>
|
||||
<keygen id='k'></keygen>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 345624 **/
|
||||
|
||||
var gInvalid = false;
|
||||
|
||||
function invalidEventHandler(aEvent)
|
||||
{
|
||||
function checkInvalidEvent(aEvent)
|
||||
{
|
||||
is(aEvent.type, "invalid", "Invalid event type should be invalid");
|
||||
ok(!aEvent.bubbles, "Invalid event should not bubble");
|
||||
ok(aEvent.cancelable, "Invalid event should be cancelable");
|
||||
}
|
||||
|
||||
checkInvalidEvent(aEvent);
|
||||
|
||||
gInvalid = true;
|
||||
}
|
||||
|
||||
function checkConstraintValidationAPIExist(element)
|
||||
{
|
||||
ok('willValidate' in element, "willValidate is not available in the DOM");
|
||||
ok('validationMessage' in element, "validationMessage is not available in the DOM");
|
||||
ok('validity' in element, "validity is not available in the DOM");
|
||||
|
||||
if ('validity' in element) {
|
||||
validity = element.validity;
|
||||
ok('valueMissing' in validity, "validity.valueMissing is not available in the DOM");
|
||||
ok('typeMismatch' in validity, "validity.typeMismatch is not available in the DOM");
|
||||
ok('patternMismatch' in validity, "validity.patternMismatch is not available in the DOM");
|
||||
ok('tooLong' in validity, "validity.tooLong is not available in the DOM");
|
||||
ok('rangeUnderflow' in validity, "validity.rangeUnderflow is not available in the DOM");
|
||||
ok('rangeOverflow' in validity, "validity.rangeOverflow is not available in the DOM");
|
||||
ok('stepMismatch' in validity, "validity.stepMismatch is not available in the DOM");
|
||||
ok('customError' in validity, "validity.customError is not available in the DOM");
|
||||
ok('valid' in validity, "validity.valid is not available in the DOM");
|
||||
}
|
||||
}
|
||||
|
||||
function checkConstraintValidationAPIDefaultValues(element)
|
||||
{
|
||||
// Not checking willValidate because the default value depends of the element
|
||||
|
||||
is(element.validationMessage, "", "validationMessage default value should be empty string");
|
||||
|
||||
ok(!element.validity.valueMissing, "The element should not suffer from a constraint validation");
|
||||
ok(!element.validity.typeMismatch, "The element should not suffer from a constraint validation");
|
||||
ok(!element.validity.patternMismatch, "The element should not suffer from a constraint validation");
|
||||
ok(!element.validity.tooLong, "The element should not suffer from a constraint validation");
|
||||
ok(!element.validity.rangeUnderflow, "The element should not suffer from a constraint validation");
|
||||
ok(!element.validity.rangeOverflow, "The element should not suffer from a constraint validation");
|
||||
ok(!element.validity.stepMismatch, "The element should not suffer from a constraint validation");
|
||||
ok(!element.validity.customError, "The element should not suffer from a constraint validation");
|
||||
ok(element.validity.valid, "The element should be valid by default");
|
||||
|
||||
ok(element.checkValidity(), "The element should be valid by default");
|
||||
}
|
||||
|
||||
function checkSpecificWillValidate()
|
||||
{
|
||||
// fieldset, keygen (TODO) and select elements
|
||||
ok(!document.getElementById('f').willValidate, "Fielset element should be barred from constraint validation");
|
||||
todo(!document.getElementById('k').willValidate, "Keygen element should be barred from constraint validation");
|
||||
ok(document.getElementById('s').willValidate, "Select element should not be barred from constraint validation");
|
||||
|
||||
// input element
|
||||
i = document.getElementById('i');
|
||||
i.type = "hidden";
|
||||
ok(!i.willValidate, "Hidden state input should be barred from constraint validation");
|
||||
i.type = "reset";
|
||||
ok(!i.willValidate, "Reset button state input should be barred from constraint validation");
|
||||
i.type = "button";
|
||||
ok(!i.willValidate, "Button state input should be barred from constraint validation");
|
||||
i.type = "";
|
||||
i.readOnly = 'true';
|
||||
ok(!i.willValidate, "Readonly input should be barred from constraint validation");
|
||||
i.removeAttribute('readOnly');
|
||||
ok(i.willValidate, "Default input element should not be barred from constraint validation");
|
||||
|
||||
// button element
|
||||
b = document.getElementById('b');
|
||||
b.type = "reset";
|
||||
ok(!b.willValidate, "Reset state button should be barred from constraint validation");
|
||||
b.type = "button";
|
||||
ok(!b.willValidate, "Button state button should be barred from constraint validation");
|
||||
b.type = "";
|
||||
ok(b.willValidate, "Default button element should not be barred from constraint validation");
|
||||
|
||||
// textarea element
|
||||
t = document.getElementById('t');
|
||||
t.readOnly = true;
|
||||
ok(!t.willValidate, "Readonly textarea should be barred from constraint validation");
|
||||
t.removeAttribute('readOnly');
|
||||
ok(t.willValidate, "Default textarea element should not be barred from constraint validation");
|
||||
|
||||
// TODO: output elements are always barred from constraint validation.
|
||||
// TODO: PROGRESS
|
||||
// TODO: METER
|
||||
}
|
||||
|
||||
function checkCommonWillValidate(element)
|
||||
{
|
||||
// Not checking the default value because it has been check previously
|
||||
|
||||
element.disabled = true;
|
||||
ok(!element.willValidate, "Disabled element should be barred from constraint validation");
|
||||
element.removeAttribute('disabled');
|
||||
|
||||
// TODO: If an element has a datalist element ancestor, it is barred from constraint validation.
|
||||
}
|
||||
|
||||
function checkCustomError(element)
|
||||
{
|
||||
element.setCustomValidity("message");
|
||||
is(element.validationMessage, "message", "When the element has a custom validity message, validation message should return it");
|
||||
ok(element.validity.customError, "The element should suffer from a custom error");
|
||||
ok(!element.validity.valid, "The element should not be valid with a custom error");
|
||||
|
||||
element.setCustomValidity("");
|
||||
is(element.validationMessage, "", "The element should not have a validation message when reseted");
|
||||
ok(!element.validity.customError, "The element should not suffer anymore from a custom error");
|
||||
ok(element.validity.valid, "The element should now be valid");
|
||||
}
|
||||
|
||||
function checkCheckValidity(element)
|
||||
{
|
||||
element.setCustomValidity("message");
|
||||
ok(!element.checkValidity(), "checkValidity() should return false when the element is not valid");
|
||||
|
||||
ok(gInvalid, "Invalid event should have been handled");
|
||||
|
||||
gInvalid = false;
|
||||
element.setCustomValidity("");
|
||||
|
||||
ok(element.checkValidity(), "Element should be valid");
|
||||
ok(!gInvalid, "Invalid event should not have been handled");
|
||||
}
|
||||
|
||||
function checkValidityStateObjectAliveWithoutElement(element)
|
||||
{
|
||||
// We are creating a temporary element and getting it's ValidityState object.
|
||||
// Then, we make sure it is removed by the garbage collector and we check the
|
||||
// ValidityState default values (it should not crash).
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var v = document.createElement(element).validity;
|
||||
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
||||
getInterface(Components.interfaces.nsIDOMWindowUtils).garbageCollect();
|
||||
|
||||
ok(!v.valueMissing,
|
||||
"When the element is not alive, it shouldn't suffer from constraint validation");
|
||||
ok(!v.typeMismatch,
|
||||
"When the element is not alive, it shouldn't suffer from constraint validation");
|
||||
ok(!v.patternMismatch,
|
||||
"When the element is not alive, it shouldn't suffer from constraint validation");
|
||||
ok(!v.tooLong,
|
||||
"When the element is not alive, it shouldn't suffer from constraint validation");
|
||||
ok(!v.rangeUnderflow,
|
||||
"When the element is not alive, it shouldn't suffer from constraint validation");
|
||||
ok(!v.rangeOverflow,
|
||||
"When the element is not alive, it shouldn't suffer from constraint validation");
|
||||
ok(!v.stepMismatch,
|
||||
"When the element is not alive, it shouldn't suffer from constraint validation");
|
||||
ok(!v.customError,
|
||||
"When the element is not alive, it shouldn't suffer from constraint validation");
|
||||
ok(v.valid, "When the element is not alive, it should be valid");
|
||||
}
|
||||
|
||||
/* TODO: add <output> element when it will be implemented */
|
||||
checkConstraintValidationAPIExist(document.getElementById('f'));
|
||||
checkConstraintValidationAPIExist(document.getElementById('i'));
|
||||
checkConstraintValidationAPIExist(document.getElementById('b'));
|
||||
checkConstraintValidationAPIExist(document.getElementById('s'));
|
||||
checkConstraintValidationAPIExist(document.getElementById('t'));
|
||||
checkConstraintValidationAPIExist(document.getElementById('k'));
|
||||
|
||||
/* TODO: add <output> element when it will be implemented */
|
||||
checkConstraintValidationAPIDefaultValues(document.getElementById('f'));
|
||||
checkConstraintValidationAPIDefaultValues(document.getElementById('i'));
|
||||
checkConstraintValidationAPIDefaultValues(document.getElementById('b'));
|
||||
checkConstraintValidationAPIDefaultValues(document.getElementById('s'));
|
||||
checkConstraintValidationAPIDefaultValues(document.getElementById('t'));
|
||||
checkConstraintValidationAPIDefaultValues(document.getElementById('k'));
|
||||
|
||||
checkSpecificWillValidate();
|
||||
|
||||
// Not checking fieldset, output and keygen
|
||||
// because they are always barred from constraint validation.
|
||||
checkCommonWillValidate(document.getElementById('i'));
|
||||
checkCommonWillValidate(document.getElementById('b'));
|
||||
checkCommonWillValidate(document.getElementById('s'));
|
||||
checkCommonWillValidate(document.getElementById('t'));
|
||||
|
||||
// Not checking fieldset, output and keygen
|
||||
// because they are always barred from constraint validation.
|
||||
checkCustomError(document.getElementById('i'));
|
||||
checkCustomError(document.getElementById('b'));
|
||||
checkCustomError(document.getElementById('s'));
|
||||
checkCustomError(document.getElementById('t'));
|
||||
|
||||
// Not checking fieldset, output and keygen
|
||||
// because they are always barred from constraint validation.
|
||||
checkCheckValidity(document.getElementById('i'));
|
||||
checkCheckValidity(document.getElementById('b'));
|
||||
checkCheckValidity(document.getElementById('s'));
|
||||
checkCheckValidity(document.getElementById('t'));
|
||||
|
||||
/* TODO: add "output" and "keygen" elements */
|
||||
checkValidityStateObjectAliveWithoutElement("fieldset");
|
||||
checkValidityStateObjectAliveWithoutElement("input");
|
||||
checkValidityStateObjectAliveWithoutElement("button");
|
||||
checkValidityStateObjectAliveWithoutElement("select");
|
||||
checkValidityStateObjectAliveWithoutElement("textarea");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=345624
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 345624</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=345624">Mozilla Bug 345624</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<input id='i'>
|
||||
<textarea id='t'></textarea>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 345624 **/
|
||||
|
||||
/**
|
||||
* This test is checking only tooLong related features
|
||||
* related to constraint validation.
|
||||
*/
|
||||
|
||||
function checkTooLongValidity(element)
|
||||
{
|
||||
element.value = "foo";
|
||||
ok(!element.validity.tooLong,
|
||||
"Element should not be too long when maxlength is not set");
|
||||
|
||||
element.maxLength = 3;
|
||||
ok(!element.validity.tooLong,
|
||||
"Element should not be to long when maxlength = value length");
|
||||
|
||||
element.maxLength = 5;
|
||||
ok(!element.validity.tooLong,
|
||||
"Element should not be too long when maxlength > value length");
|
||||
|
||||
ok(element.validity.valid, "Element should be valid");
|
||||
|
||||
element.maxLength = 2;
|
||||
ok(element.validity.tooLong,
|
||||
"Element should be too long when maxlength < value length");
|
||||
|
||||
ok(!element.validity.valid,
|
||||
"Element should not be valid when it is too long");
|
||||
|
||||
is(element.validationMessage,
|
||||
"The text is too long. It is 3 characters long and the limit is 2.",
|
||||
"The validation message text is not correct");
|
||||
ok(!element.checkValidity(), "The element should not be valid");
|
||||
element.setCustomValidity("custom message");
|
||||
is(element.validationMessage, "custom message",
|
||||
"Custom message should be shown instead of too long one");
|
||||
}
|
||||
|
||||
checkTooLongValidity(document.getElementById('i'));
|
||||
checkTooLongValidity(document.getElementById('t'));
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,322 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=345822
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 345822</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=345822">Mozilla Bug 345822</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<form>
|
||||
<input name="input" id='i'>
|
||||
<input name="input" id='r' type='radio'>
|
||||
<textarea name="textarea" id='t'></textarea>
|
||||
</form>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 345822 **/
|
||||
|
||||
function checkRequiredAttribute(element)
|
||||
{
|
||||
ok('required' in element, "Element should have the required attribute");
|
||||
|
||||
ok(!element.required, "Element required attribute should be disabled");
|
||||
is(element.getAttribute('required'), null,
|
||||
"Element required attribute should be disabled");
|
||||
|
||||
element.required = true;
|
||||
ok(element.required, "Element required attribute should be enabled");
|
||||
isnot(element.getAttribute('required'), null,
|
||||
"Element required attribute should be enabled");
|
||||
|
||||
element.removeAttribute('required');
|
||||
element.setAttribute('required', '');
|
||||
ok(element.required, "Element required attribute should be enabled");
|
||||
isnot(element.getAttribute('required'), null,
|
||||
"Element required attribute should be enabled");
|
||||
|
||||
element.removeAttribute('required');
|
||||
ok(!element.required, "Element required attribute should be disabled");
|
||||
is(element.getAttribute('required'), null,
|
||||
"Element required attribute should be disabled");
|
||||
}
|
||||
|
||||
function checkNotSufferingFromBeingMissing(element)
|
||||
{
|
||||
ok(!element.validity.valueMissing,
|
||||
"Element should not suffer from value missing");
|
||||
ok(element.validity.valid, "Element should be valid");
|
||||
ok(element.checkValidity(), "Element should be valid");
|
||||
is(element.validationMessage, "",
|
||||
"Validation message should be the empty string");
|
||||
}
|
||||
|
||||
function checkSufferingFromBeingMissing(element)
|
||||
{
|
||||
ok(element.validity.valueMissing, "Element should suffer from value missing");
|
||||
ok(!element.validity.valid, "Element should not be valid");
|
||||
ok(!element.checkValidity(), "Element should not be valid");
|
||||
|
||||
if (element.type == 'checkbox')
|
||||
{
|
||||
is(element.validationMessage,
|
||||
"This checkbox is mandatory, you have to check it.",
|
||||
"Validation message is wrong");
|
||||
}
|
||||
else if (element.type == 'radio')
|
||||
{
|
||||
is(element.validationMessage,
|
||||
"You have to select one of these options.",
|
||||
"Validation message is wrong");
|
||||
}
|
||||
else if (element.type == 'file')
|
||||
{
|
||||
is(element.validationMessage,
|
||||
"You have to select a file.",
|
||||
"Validation message is wrong");
|
||||
}
|
||||
else // text fields
|
||||
{
|
||||
is(element.validationMessage,
|
||||
"This field is mandatory, you have to fill it.",
|
||||
"Validation message is wrong");
|
||||
}
|
||||
}
|
||||
|
||||
function checkTextareaRequiredValidity(element)
|
||||
{
|
||||
element.value = '';
|
||||
element.required = false;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.required = true;
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element.readOnly = true;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.readOnly = false;
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element.value = 'foo';
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.value = '';
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element.required = false;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
}
|
||||
|
||||
function checkInputRequiredNotApply(element)
|
||||
{
|
||||
element.value = '';
|
||||
element.required = false;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.required = true;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.required = false;
|
||||
}
|
||||
|
||||
function checkInputRequiredValidity(element)
|
||||
{
|
||||
element.value = '';
|
||||
element.required = false;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.required = true;
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element.readOnly = true;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.readOnly = false;
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
if (element.type == 'email') {
|
||||
element.value = 'foo@bar.com';
|
||||
} else if (element.type == 'url') {
|
||||
element.value = 'http://mozilla.org/';
|
||||
} else {
|
||||
element.value = 'foo';
|
||||
}
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.value = '';
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element.required = false;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
}
|
||||
|
||||
function checkInputRequiredValidityForCheckbox(element)
|
||||
{
|
||||
element.checked = false;
|
||||
element.required = false;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.required = true;
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element.checked = true;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.checked = false;
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element.required = false;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
}
|
||||
|
||||
function checkInputRequiredValidityForRadio(element)
|
||||
{
|
||||
element.checked = false;
|
||||
element.required = false;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.required = true;
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element.checked = true;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.checked = false;
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element.required = false;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
// A required radio button should not suffer from value missing if another
|
||||
// radio button from the same group is checked.
|
||||
var element2 = document.createElement('input');//document.getElementById('r');
|
||||
document.forms[0].appendChild(element2);
|
||||
element2.name = 'input';
|
||||
element2.type = 'radio';
|
||||
element2.checked = false;
|
||||
element2.required = false;
|
||||
|
||||
element.checked = false;
|
||||
element.required = true;
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element2.checked = true;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
// The other radio button should not be disabled.
|
||||
// A disabled checked radio button in the radio group
|
||||
// is enough to not suffer from value missing.
|
||||
element2.disabled = true;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
// If a radio button is not required but another radio button is required in
|
||||
// the same group, the not required radio button should not suffer from value
|
||||
// missing.
|
||||
element2.disabled = false;
|
||||
element2.checked = false;
|
||||
element.required = false;
|
||||
element2.required = true;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
checkSufferingFromBeingMissing(element2);
|
||||
}
|
||||
|
||||
function checkInputRequiredValidityForFile(element)
|
||||
{
|
||||
function createFileWithData(fileName, fileData) {
|
||||
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties);
|
||||
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
|
||||
testFile.append(fileName);
|
||||
var outStream = Components.
|
||||
classes["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
|
||||
0666, 0);
|
||||
outStream.write(fileData, fileData.length);
|
||||
outStream.close();
|
||||
|
||||
return testFile;
|
||||
}
|
||||
|
||||
// Need privileges to set a filename with .value.
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
var file = createFileWithData("345822_file", "file content");
|
||||
|
||||
element.value = "";
|
||||
element.required = false;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.required = true;
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element.value = file.path;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
element.value = "";
|
||||
checkSufferingFromBeingMissing(element);
|
||||
|
||||
element.required = false;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
file.remove(false);
|
||||
}
|
||||
|
||||
var textarea = document.getElementById('t');
|
||||
var input = document.getElementById('i');
|
||||
|
||||
checkRequiredAttribute(textarea);
|
||||
checkTextareaRequiredValidity(textarea);
|
||||
|
||||
// Every input element should have the required attribute.
|
||||
checkRequiredAttribute(input);
|
||||
|
||||
// The required attribute behavior depend of the input type.
|
||||
// First of all, checks for the types which do not use the required attribute.
|
||||
// TODO: check 'color' and 'range' when they will be implemented.
|
||||
input.type = 'hidden';
|
||||
checkInputRequiredNotApply(input);
|
||||
input.type = 'submit';
|
||||
checkInputRequiredNotApply(input);
|
||||
input.type = 'button';
|
||||
checkInputRequiredNotApply(input);
|
||||
input.type = 'reset';
|
||||
checkInputRequiredNotApply(input);
|
||||
input.type = 'image';
|
||||
checkInputRequiredNotApply(input);
|
||||
|
||||
// Now, checking for all types which accept the required attribute.
|
||||
// TODO: check 'datetime', 'date', 'month', 'week', 'time', 'datetime-local'
|
||||
// and 'number' when they will be implemented.
|
||||
input.type = 'text';
|
||||
checkInputRequiredValidity(input);
|
||||
input.type = 'password';
|
||||
checkInputRequiredValidity(input);
|
||||
input.type = 'checkbox';
|
||||
checkInputRequiredValidityForCheckbox(input);
|
||||
input.type = 'radio';
|
||||
checkInputRequiredValidityForRadio(input);
|
||||
input.type = 'file';
|
||||
checkInputRequiredValidityForFile(input);
|
||||
input.type = 'search';
|
||||
checkInputRequiredValidity(input);
|
||||
input.type = 'tel';
|
||||
checkInputRequiredValidity(input);
|
||||
input.type = 'email';
|
||||
checkInputRequiredValidity(input);
|
||||
input.type = 'url';
|
||||
checkInputRequiredValidity(input);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -105,7 +105,6 @@ objectIfaces2.push("nsIImageLoadingContent");
|
|||
ol
|
||||
param
|
||||
q
|
||||
spacer
|
||||
ul
|
||||
wbr
|
||||
head
|
||||
|
@ -210,7 +209,6 @@ HTML_TAG("script", "Script", [], [ "nsIScriptLoaderObserver" ]);
|
|||
HTML_TAG("section", "") // HTMLElement
|
||||
HTML_TAG("select", "Select");
|
||||
HTML_TAG("small", ""); // HTMLElement
|
||||
HTML_TAG("spacer", "Spacer");
|
||||
HTML_TAG("span", "Span");
|
||||
HTML_TAG("strike", ""); // HTMLElement
|
||||
HTML_TAG("strong", ""); // HTMLElement
|
||||
|
|
|
@ -25,6 +25,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=392567
|
|||
var dataUrl = "http://mochi.test:8888/tests/content/html/content/test/bug392567.jar";
|
||||
var jarUrl = "jar:" + dataUrl + "!/index.html";
|
||||
var httpUrl = location.href.replace(/\.html.*/, "_404");
|
||||
var previousDir = location.href.replace(/test\/[^\/]*$/, "");
|
||||
|
||||
var form = document.forms.testForm;
|
||||
var frame = frames.testFrame;
|
||||
|
@ -32,14 +33,17 @@ document.getElementById("testFrame").onload = processTestResult;
|
|||
|
||||
// List of tests to run, each test consists of form action URL and expected result URL
|
||||
var tests = [
|
||||
[jarUrl, jarUrl + "?$PARAMS"],
|
||||
[jarUrl + "?jarTest1=jarTest2", jarUrl + "?$PARAMS"],
|
||||
[jarUrl + "?jarTest3=jarTest4#jarTest5", jarUrl + "?$PARAMS#jarTest5"],
|
||||
["data:text/html,<html></html>", "data:text/html,<html></html>?$PARAMS"],
|
||||
["data:text/html,<html>How%20about%20this?</html>", "data:text/html,<html>How%20about%20this?$PARAMS"],
|
||||
[httpUrl, httpUrl + "?$PARAMS"],
|
||||
[httpUrl + "?httpTest1=httpTest2", httpUrl + "?$PARAMS"],
|
||||
[httpUrl + "?httpTest3=httpTest4#httpTest5", httpUrl + "?$PARAMS#httpTest5"]
|
||||
[jarUrl, jarUrl + "?$PARAMS", null],
|
||||
[jarUrl + "?jarTest1=jarTest2", jarUrl + "?$PARAMS", null],
|
||||
[jarUrl + "?jarTest3=jarTest4#jarTest5", jarUrl + "?$PARAMS#jarTest5", null],
|
||||
["data:text/html,<html></html>", "data:text/html,<html></html>?$PARAMS", null],
|
||||
["data:text/html,<html>How%20about%20this?</html>", "data:text/html,<html>How%20about%20this?$PARAMS", null],
|
||||
[httpUrl, httpUrl + "?$PARAMS", null],
|
||||
[httpUrl + "?httpTest1=httpTest2", httpUrl + "?$PARAMS", null ],
|
||||
[httpUrl + "?httpTest3=httpTest4#httpTest5", httpUrl + "?$PARAMS#httpTest5", null],
|
||||
["", jarUrl + "?key=value0", null],
|
||||
[" ", jarUrl + "?key=value0", document.location],
|
||||
["../", previousDir + "?$PARAMS", previousDir],
|
||||
];
|
||||
|
||||
var currentTest = -1;
|
||||
|
@ -54,7 +58,11 @@ function runNextTest() {
|
|||
return;
|
||||
}
|
||||
|
||||
form.action = tests[currentTest][0];
|
||||
form.setAttribute("action", tests[currentTest][0]);
|
||||
is(form.action, tests[currentTest][0],
|
||||
"action IDL attribute should reflect the action content attribute");
|
||||
is(form.mozActionUri, tests[currentTest][2] ? tests[currentTest][2] : tests[currentTest][0],
|
||||
"mozActionUri IDL attribute should resolve the action URI");
|
||||
form.key.value = "value" + currentTest;
|
||||
form.submit();
|
||||
}
|
||||
|
|
|
@ -26,12 +26,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=549475
|
|||
var inputTypes =
|
||||
[
|
||||
"text", "password", "search", "telephone", "hidden", "checkbox", "radio",
|
||||
"submit", "image", "reset", "button",
|
||||
"submit", "image", "reset", "button", "email", "url"
|
||||
];
|
||||
|
||||
var todoTypes =
|
||||
[
|
||||
"email", "url", "number", "range", "color",
|
||||
"number", "range", "color",
|
||||
"date", "month", "week", "time", "datetime", "datetime-local",
|
||||
];
|
||||
|
||||
|
@ -48,15 +48,10 @@ function sanitizeValue(aType, aValue)
|
|||
case "password":
|
||||
case "search":
|
||||
case "telephone":
|
||||
//case "email":
|
||||
return aValue.replace(/[\n\r]/g, "");
|
||||
case "email":
|
||||
// TODO: uncomment the previous email case when email is implemented.
|
||||
return "";
|
||||
return aValue.replace(/[\n\r]/g, "");
|
||||
case "url":
|
||||
// TODO: uncomment the next line when url is implemented.
|
||||
//return aValue.replace(/[\n\r]/g, "").replace(/^\s+|\s+$/g, ""');
|
||||
return "";
|
||||
return aValue.replace(/[\n\r]/g, "").replace(/^\s+|\s+$/g, "");
|
||||
case "date":
|
||||
case "month":
|
||||
case "week":
|
||||
|
@ -87,6 +82,7 @@ function checkSanitizing(element)
|
|||
"foo\n\rbar",
|
||||
" foo ",
|
||||
" foo\n\r bar ",
|
||||
"\r\n foobar \n\r",
|
||||
];
|
||||
|
||||
for each (value in testData) {
|
||||
|
|
|
@ -84,6 +84,7 @@ checkType(document.getElementById('b1'), document.getElementById('b2'), 'submit'
|
|||
// input types
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'button', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'checkbox', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'email', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'file', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'hidden', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'reset', wrongType);
|
||||
|
@ -93,6 +94,7 @@ checkType(document.getElementById('i1'), document.getElementById('i2'), 'text',
|
|||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'submit', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'tel', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'search', wrongType);
|
||||
checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'url', wrongType);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=555559
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 555559</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=555559">Mozilla Bug 555559</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<form>
|
||||
<input type='email' name='email' id='i' oninvalid="invalidEventHandler(event);">
|
||||
<form>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 555559 **/
|
||||
|
||||
// More checks are done in test_bug551670.html.
|
||||
|
||||
var gInvalid = false;
|
||||
|
||||
function invalidEventHandler(e)
|
||||
{
|
||||
is(e.type, "invalid", "Invalid event type should be invalid");
|
||||
gInvalid = true;
|
||||
}
|
||||
|
||||
function checkValidEmailAddress(element)
|
||||
{
|
||||
gInvalid = false;
|
||||
ok(!element.validity.typeMismatch,
|
||||
"Element should not suffer from type mismatch");
|
||||
ok(element.validity.valid, "Element should be valid");
|
||||
ok(element.checkValidity(), "Element should be valid");
|
||||
ok(!gInvalid, "The invalid event should not have been thrown");
|
||||
is(element.validationMessage, '',
|
||||
"Validation message should be the empty string");
|
||||
}
|
||||
|
||||
function checkInvalidEmailAddress(element)
|
||||
{
|
||||
gInvalid = false;
|
||||
ok(element.validity.typeMismatch,
|
||||
"Element should suffer from type mismatch");
|
||||
ok(!element.validity.valid, "Element should not be valid");
|
||||
ok(!element.checkValidity(), "Element should not be valid");
|
||||
ok(gInvalid, "The invalid event should have been thrown");
|
||||
is(element.validationMessage, "The entered email address is not valid.",
|
||||
"Validation message is not valid");
|
||||
}
|
||||
|
||||
var email = document.forms[0].elements[0];
|
||||
is(email.type, 'email', "email state should be recognized");
|
||||
|
||||
// This is not really a valid email address
|
||||
// but it should not be considered as invalid.
|
||||
email.value = '';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = ' foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com ';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'tulip';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
// Some checks on the user part of the address.
|
||||
email.value = '@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
var legalCharacters = "abcdefghijklmnopqrstuvwxyz";
|
||||
legalCharacters += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
legalCharacters += "0123456789";
|
||||
legalCharacters += "!#$%&'*+-/=?^_`{|}~.";
|
||||
|
||||
for each (c in legalCharacters)
|
||||
{
|
||||
email.value = c + '@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
}
|
||||
|
||||
email.value = legalCharacters + '@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
// Checking stripped characters.
|
||||
email.value = 'f\noo@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'f\roo@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
// Testing some illegal characters.
|
||||
var illegalCharacters = "()<>[]:;@\, \t";
|
||||
|
||||
for each (c in illegalCharacters)
|
||||
{
|
||||
email.value = c + '@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
}
|
||||
|
||||
// Some checks on the domain part of the address.
|
||||
email.value = 'foo@bar';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@b';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@foo.bar';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@foo..bar';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@.bar';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@tulip.foo.bar';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@tulip.foo-bar';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@1.2';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@127.0.0.1';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@1.2.3.';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
// Checking stripped characters.
|
||||
email.value = 'foo@b\nar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@b\rar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
// Testing some illegal characters.
|
||||
illegalCharacters = "()<>[]:;@\,!#$%&'*+/=?^_`{|}~ \t";
|
||||
|
||||
for each (c in illegalCharacters)
|
||||
{
|
||||
email.value = 'foo@foo.bar' + c;
|
||||
checkInvalidEmailAddress(email);
|
||||
}
|
||||
|
||||
// Testing multiple: we are not going to re-test email validity, just multiple.
|
||||
email.multiple = true;
|
||||
|
||||
email.value = 'foo@bar.com, foo@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com,foo@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com,foo@bar.com,foo@bar.com';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = ' foo@bar.com , foo@bar.com ';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = '\tfoo@bar.com\t,\tfoo@bar.com\t';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = '\rfoo@bar.com\r,\rfoo@bar.com\r';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = '\nfoo@bar.com\n,\nfoo@bar.com\n';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = '\ffoo@bar.com\f,\ffoo@bar.com\f';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = '\t foo@bar.com\r,\nfoo@bar.com\f';
|
||||
checkValidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@b,ar.com,foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com,foo@bar.com,';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = ' foo@bar.com , foo@bar.com , ';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = ',foo@bar.com,foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = ',foo@bar.com,foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com,,,foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com;foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = '<foo@bar.com>, <foo@bar.com>';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar, foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo@bar.com, foo';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
email.value = 'foo, foo@bar.com';
|
||||
checkInvalidEmailAddress(email);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче