Merge mozilla-central to mozilla-inbound

This commit is contained in:
Ed Morley 2011-12-20 11:52:08 +00:00
commit 1a39d3c95a
217 changed files with 11047 additions and 5363 deletions

View File

@ -931,12 +931,18 @@ pref("browser.taskbar.lists.refreshInSeconds", 120);
#ifdef MOZ_SERVICES_SYNC
// The sync engines to use.
pref("services.sync.registerEngines", "Bookmarks,Form,History,Password,Prefs,Tab");
pref("services.sync.registerEngines", "Bookmarks,Form,History,Password,Prefs,Tab,Addons");
// Preferences to be synced by default
pref("services.sync.prefs.sync.accessibility.blockautorefresh", true);
pref("services.sync.prefs.sync.accessibility.browsewithcaret", true);
pref("services.sync.prefs.sync.accessibility.typeaheadfind", true);
pref("services.sync.prefs.sync.accessibility.typeaheadfind.linksonly", true);
pref("services.sync.prefs.sync.addons.ignoreUserEnabledChanges", true);
// The addons prefs related to repository verification are intentionally
// not synced for security reasons. If a system is compromised, a user
// could weaken the pref locally, install an add-on from an untrusted
// source, and this would propagate automatically to other,
// uncompromised Sync-connected devices.
pref("services.sync.prefs.sync.app.update.mode", true);
pref("services.sync.prefs.sync.browser.download.manager.closeWhenDone", true);
pref("services.sync.prefs.sync.browser.download.manager.retention", true);

View File

@ -8800,7 +8800,7 @@ function switchToTabHavingURI(aURI, aOpenNew) {
if (isBrowserWindow && isTabEmpty(gBrowser.selectedTab))
gBrowser.selectedBrowser.loadURI(aURI.spec);
else
openUILinkIn(aURI.spec, "tab", { inBackground: false });
openUILinkIn(aURI.spec, "tab");
}
return false;
@ -8910,20 +8910,16 @@ function duplicateTabIn(aTab, where, delta) {
.getService(Ci.nsISessionStore)
.duplicateTab(window, aTab, delta);
var loadInBackground =
getBoolPref("browser.tabs.loadBookmarksInBackground", false);
switch (where) {
case "window":
gBrowser.hideTab(newTab);
gBrowser.replaceTabWithWindow(newTab);
break;
case "tabshifted":
loadInBackground = !loadInBackground;
// fall through
// A background tab has been opened, nothing else to do here.
break;
case "tab":
if (!loadInBackground)
gBrowser.selectedTab = newTab;
gBrowser.selectedTab = newTab;
break;
}
}

View File

@ -55,6 +55,7 @@
<?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/places/places.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/devtools/common.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/devtools/webconsole.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
@ -971,7 +972,9 @@
<splitter id="devtools-side-splitter" hidden="true"/>
<vbox id="devtools-sidebar-box" hidden="true"
style="min-width: 18em; width: 22em; max-width: 42em;" persist="width">
<toolbar id="devtools-sidebar-toolbar" nowindowdrag="true"/>
<toolbar id="devtools-sidebar-toolbar"
class="devtools-toolbar"
nowindowdrag="true"/>
<deck id="devtools-sidebar-deck" flex="1"/>
</vbox>
<vbox id="browser-border-end" hidden="true" layer="true"/>
@ -987,6 +990,7 @@
<vbox id="browser-bottombox" layer="true">
<toolbar id="inspector-toolbar"
class="devtools-toolbar"
nowindowdrag="true"
hidden="true">
<vbox flex="1">
@ -1001,6 +1005,7 @@
tooltiptext="&inspectCloseButton.tooltiptext;"/>
#endif
<toolbarbutton id="inspector-inspect-toolbutton"
class="devtools-toolbarbutton"
label="&inspectButton.label;"
accesskey="&inspectButton.accesskey;"
command="Inspector:Inspect"/>
@ -1009,11 +1014,13 @@
clicktoscroll="true"/>
<hbox id="inspector-tools">
<toolbarbutton id="inspector-3D-button"
class="devtools-toolbarbutton"
hidden="true"
label="&inspect3DButton.label;"
accesskey="&inspect3DButton.accesskey;"
command="Inspector:Tilt"/>
<toolbarbutton id="inspector-style-button"
class="devtools-toolbarbutton"
label="&inspectStyleButton.label;"
accesskey="&inspectStyleButton.accesskey;"
command="Inspector:Sidebar"/>

View File

@ -582,7 +582,8 @@ var gSyncSetup = {
return document.getElementById(element).hasAttribute("checked");
}
let prefs = ["engine.bookmarks", "engine.passwords", "engine.history", "engine.tabs", "engine.prefs"];
let prefs = ["engine.bookmarks", "engine.passwords", "engine.history",
"engine.tabs", "engine.prefs", "engine.addons"];
for (let i = 0;i < prefs.length;i++) {
Weave.Svc.Prefs.set(prefs[i], isChecked(prefs[i]));
}

View File

@ -120,7 +120,7 @@
onpageshow="gSyncSetup.onPageShow()">
<vbox align="center" flex="1">
<description style="padding: 0 7em;">
&setup.pickSetupType.description;
&setup.pickSetupType.description2;
</description>
<spacer flex="3"/>
<button id="newAccount"
@ -428,6 +428,10 @@
accesskey="&engine.tabs.accesskey;"
id="engine.tabs"
checked="true"/>
<checkbox label="&engine.addons.label;"
accesskey="&engine.addons.accesskey;"
id="engine.addons"
checked="true"/>
</vbox>
</row>
</rows>

View File

@ -35,24 +35,19 @@
* ***** END LICENSE BLOCK ***** */
function test() {
let backgroundPref = "browser.tabs.loadBookmarksInBackground";
let newTab = gBrowser.addTab("http://example.com");
waitForExplicitFinish();
newTab.linkedBrowser.addEventListener("load", mainPart, true);
Services.prefs.setBoolPref(backgroundPref, true);
function mainPart() {
newTab.linkedBrowser.removeEventListener("load", mainPart, true);
gBrowser.pinTab(newTab);
gBrowser.selectedTab = newTab;
openUILinkIn("http://example.org/", "current");
openUILinkIn("http://example.org/", "current", { inBackground: true });
isnot(gBrowser.selectedTab, newTab, "shouldn't load in background");
if (Services.prefs.prefHasUserValue(backgroundPref))
Services.prefs.clearUserPref(backgroundPref);
gBrowser.removeTab(newTab);
gBrowser.removeTab(gBrowser.tabs[1]); // example.org tab
finish();

View File

@ -363,8 +363,6 @@
} else {
this.handleRevert();
let params = { allowThirdPartyFixup: true, postData: postData };
if (altEnter)
params.inBackground = false;
if (!this.valueIsTyped)
params.isUTF8 = true;
openUILinkIn(url, where, params);

View File

@ -100,12 +100,7 @@ function openUILink( url, e, ignoreButton, ignoreAlt, allowKeywordFixup, postDat
* Ctrl+Shift new tab, in background
* Alt save
*
* You can swap Ctrl and Ctrl+shift by toggling the hidden pref
* browser.tabs.loadBookmarksInBackground (not browser.tabs.loadInBackground, which
* is for content area links).
*
* Middle-clicking is the same as Ctrl+clicking (it opens a new tab) and it is
* subject to the shift modifier and pref in the same way.
* Middle-clicking is the same as Ctrl+clicking (it opens a new tab).
*
* Exceptions:
* - Alt is ignored for menu items selected using the keyboard so you don't accidentally save stuff.
@ -249,7 +244,7 @@ function openLinkIn(url, where, params) {
let loadInBackground = aInBackground;
if (loadInBackground == null) {
loadInBackground = aFromChrome ?
getBoolPref("browser.tabs.loadBookmarksInBackground") :
false :
getBoolPref("browser.tabs.loadInBackground");
}

View File

@ -729,7 +729,9 @@ var PlacesUIUtils = {
}
}
}
aWindow.openUILinkIn(aNode.uri, aWhere);
aWindow.openUILinkIn(aNode.uri, aWhere, {
inBackground: Services.prefs.getBoolPref("browser.tabs.loadBookmarksInBackground")
});
}
},

View File

@ -62,6 +62,7 @@
<preference id="engine.tabs" name="services.sync.engine.tabs" type="bool"/>
<preference id="engine.prefs" name="services.sync.engine.prefs" type="bool"/>
<preference id="engine.passwords" name="services.sync.engine.passwords" type="bool"/>
<preference id="engine.addons" name="services.sync.engine.addons" type="bool"/>
</preferences>
@ -152,6 +153,11 @@
accesskey="&engine.tabs.accesskey;"
preference="engine.tabs"/>
</richlistitem>
<richlistitem>
<checkbox label="&engine.addons.label;"
accesskey="&engine.addons.accesskey;"
preference="engine.addons"/>
</richlistitem>
</richlistbox>
</vbox>
</groupbox>

View File

@ -1672,6 +1672,7 @@ InspectorUI.prototype = {
btn = this.chromeDoc.createElement("toolbarbutton");
let buttonId = this.getToolbarButtonId(aRegObj.id);
btn.setAttribute("id", buttonId);
btn.setAttribute("class", "devtools-toolbarbutton");
btn.setAttribute("label", aRegObj.label);
btn.setAttribute("tooltiptext", aRegObj.tooltiptext);
btn.setAttribute("accesskey", aRegObj.accesskey);
@ -1733,6 +1734,7 @@ InspectorUI.prototype = {
btn.id = buttonId;
btn.setAttribute("label", aRegObj.label);
btn.setAttribute("class", "devtools-toolbarbutton");
btn.setAttribute("tooltiptext", aRegObj.tooltiptext);
btn.setAttribute("accesskey", aRegObj.accesskey);
btn.setAttribute("image", aRegObj.icon || "");

View File

@ -13,6 +13,8 @@ Orion version: git clone from 2011-12-09
+ patch for Eclipse Bug 366312 - right-clicking outside of the selection causes the caret to move
https://github.com/mihaisucan/orion.client/tree/bug-366312
see https://bugs.eclipse.org/bugs/show_bug.cgi?id=366312
+ patch for Mozilla Bug 711737 - Orion should support all the CSS properties from CSS1, CSS2, CSS2.1 and CSS3
https://bugzilla.mozilla.org/show_bug.cgi?id=711737
# License

View File

@ -2,124 +2,127 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
.viewContainer {
background: -moz-Dialog;
font-family: monospace;
font-size: inherit; /* inherit browser's default monospace font size */
background: #cddae5; /* This will be seen as the continuation of the ruler */
font-family: monospace;
font-size: inherit; /* inherit browser's default monospace font size */
}
.view {
background: #fff;
background: #f0f0ff; /* Background of the editor */
padding-left: 0;
}
.readonly > .view {
background: #f6f6f6;
background: #f0f0ff;
}
/* One line */
.viewContent > div {
padding-left: 4px; /* Margin between the ruler and the editor */
}
/* Styles for rulers */
.ruler {
background-color: white;
}
.ruler.lines {
border-right: 1px solid lightgray;
text-align: right;
text-align: right;
}
/* Styles for the line number ruler */
.rulerLines {
background: -moz-Dialog;
color: -moz-DialogText;
min-width: 1.4em;
padding-left: 4px;
padding-right: 4px;
text-align: end;
border-right: 1px solid #b4c4d3;
background: #cddae5;
color: #7a8a99;
min-width: 1.4em;
padding-left: 4px;
padding-right: 4px;
text-align: end;
}
.token_singleline_comment {
color: green;
color: #45a946; /* green */
}
.token_multiline_comment {
color: green;
color: #45a946; /* green */
}
.token_doc_comment {
color: #00008F;
color: #45a946; /* green */
}
.token_doc_html_markup {
color: #7F7F9F;
color: #dd0058; /* purple */
}
.token_doc_tag {
color: #7F9FBF;
color: #dd0058; /* purple */
}
.token_task_tag {
color: #7F9FBF;
.token_task_tag { /* "TODO" */
color: black;
background: yellow;
}
.token_string {
color: blue;
color: #1e66b1; /* blue */
font-style: italic;
}
.token_keyword {
color: darkred;
font-weight: bold;
color: #dd0058; /* purple */
}
.token_space {
/* images/white_space.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAIAAABv85FHAAAABnRSTlMA/wAAAACkwsAdAAAAIUlEQVR4nGP4z8CAC+GUIEXuABhgkTuABEiRw2cmae4EAH05X7xDolNRAAAAAElFTkSuQmCC");
background-repeat: no-repeat;
background-position: center center;
/* images/white_space.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAIAAABv85FHAAAABnRSTlMA/wAAAACkwsAdAAAAIUlEQVR4nGP4z8CAC+GUIEXuABhgkTuABEiRw2cmae4EAH05X7xDolNRAAAAAElFTkSuQmCC");
background-repeat: no-repeat;
background-position: center center;
}
.token_tab {
/* images/white_tab.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAJCAIAAACJ2loDAAAABnRSTlMA/wD/AP83WBt9AAAAMklEQVR4nGP4TwRgoK6i52c3bz5w6zMSA6tJn28d2Lx589nnCAYu63AaSLxJRLoJPwAAeNk0aG4opfMAAAAASUVORK5CYII=");
background-repeat: no-repeat;
background-position: left center;
/* images/white_tab.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAJCAIAAACJ2loDAAAABnRSTlMA/wD/AP83WBt9AAAAMklEQVR4nGP4TwRgoK6i52c3bz5w6zMSA6tJn28d2Lx589nnCAYu63AaSLxJRLoJPwAAeNk0aG4opfMAAAAASUVORK5CYII=");
background-repeat: no-repeat;
background-position: left center;
}
.line_caret {
background: #EAF2FE;
.line_caret { /* Current line */
background: #dae2ee; /* lighter than the background */
}
.readonly .line_caret {
background: #fcfcfc;
background: #cddae5; /* a bit darker than the background */
}
/* Styling for html syntax highlighting */
.entity-name-tag {
color: #3f7f7f;
color: #dd0058; /* purple */
}
.entity-other-attribute-name {
color: #7f007f;
color: #dd0058; /* purple */
}
.punctuation-definition-comment {
color: #3f5fbf;
color: #45a946; /* green */
}
.comment {
color: #3f5fbf
color: #45a946; /* green */
}
.string-quoted {
color: #2a00ff;
font-style: italic;
color: #1e66b1; /* blue */
font-style: italic;
}
.invalid {
color: red;
font-weight: bold;
color: red;
font-weight: bold;
}
.annotationRange.currentBracket {
}
.annotationRange.matchingBracket {
outline: 1px solid red;
outline: 1px solid grey;
}

View File

@ -10472,24 +10472,42 @@ define(['orion/textview/annotations'], function(mAnnotations) {
"while"];
var CSS_KEYWORDS =
["color", "text-align", "text-indent", "text-decoration",
"font", "font-style", "font-family", "font-weight", "font-size", "font-variant", "line-height",
"background", "background-color", "background-image", "background-position", "background-repeat", "background-attachment",
"list-style", "list-style-image", "list-style-position", "list-style-type",
"outline", "outline-color", "outline-style", "outline-width",
"border", "border-left", "border-top", "border-bottom", "border-right", "border-color", "border-width", "border-style",
"border-bottom-color", "border-bottom-style", "border-bottom-width",
"border-left-color", "border-left-style", "border-left-width",
"border-top-color", "border-top-style", "border-top-width",
"border-right-color", "border-right-style", "border-right-width",
"padding", "padding-left", "padding-top", "padding-bottom", "padding-right",
"margin", "margin-left", "margin-top", "margin-bottom", "margin-right",
"width", "height", "left", "top", "right", "bottom",
"min-width", "max-width", "min-height", "max-height",
"display", "visibility",
"clip", "cursor", "overflow", "overflow-x", "overflow-y", "position", "z-index",
"vertical-align", "horizontal-align",
"float", "clear"
["alignment-adjust", "alignment-baseline", "animation", "animation-delay", "animation-direction", "animation-duration",
"animation-iteration-count", "animation-name", "animation-play-state", "animation-timing-function", "appearance",
"azimuth", "backface-visibility", "background", "background-attachment", "background-clip", "background-color",
"background-image", "background-origin", "background-position", "background-repeat", "background-size", "baseline-shift",
"binding", "bleed", "bookmark-label", "bookmark-level", "bookmark-state", "bookmark-target", "border", "border-bottom",
"border-bottom-color", "border-bottom-left-radius", "border-bottom-right-radius", "border-bottom-style", "border-bottom-width",
"border-collapse", "border-color", "border-image", "border-image-outset", "border-image-repeat", "border-image-slice",
"border-image-source", "border-image-width", "border-left", "border-left-color", "border-left-style", "border-left-width",
"border-radius", "border-right", "border-right-color", "border-right-style", "border-right-width", "border-spacing", "border-style",
"border-top", "border-top-color", "border-top-left-radius", "border-top-right-radius", "border-top-style", "border-top-width",
"border-width", "bottom", "box-align", "box-decoration-break", "box-direction", "box-flex", "box-flex-group", "box-lines",
"box-ordinal-group", "box-orient", "box-pack", "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
"caption-side", "clear", "clip", "color", "color-profile", "column-count", "column-fill", "column-gap", "column-rule",
"column-rule-color", "column-rule-style", "column-rule-width", "column-span", "column-width", "columns", "content", "counter-increment",
"counter-reset", "crop", "cue", "cue-after", "cue-before", "cursor", "direction", "display", "dominant-baseline",
"drop-initial-after-adjust", "drop-initial-after-align", "drop-initial-before-adjust", "drop-initial-before-align", "drop-initial-size",
"drop-initial-value", "elevation", "empty-cells", "fit", "fit-position", "float", "float-offset", "font", "font-family", "font-size",
"font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "grid-columns", "grid-rows", "hanging-punctuation",
"height", "hyphenate-after", "hyphenate-before", "hyphenate-character", "hyphenate-lines", "hyphenate-resource", "hyphens", "icon",
"image-orientation", "image-rendering", "image-resolution", "inline-box-align", "left", "letter-spacing", "line-height",
"line-stacking", "line-stacking-ruby", "line-stacking-shift", "line-stacking-strategy", "list-style", "list-style-image",
"list-style-position", "list-style-type", "margin", "margin-bottom", "margin-left", "margin-right", "margin-top", "mark", "mark-after",
"mark-before", "marks", "marquee-direction", "marquee-loop", "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
"max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", "nav-left", "nav-right", "nav-up", "opacity", "orphans",
"outline", "outline-color", "outline-offset", "outline-style", "outline-width", "overflow", "overflow-style", "overflow-x",
"overflow-y", "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", "page", "page-break-after", "page-break-before",
"page-break-inside", "page-policy", "pause", "pause-after", "pause-before", "perspective", "perspective-origin", "phonemes", "pitch",
"pitch-range", "play-during", "position", "presentation-level", "punctuation-trim", "quotes", "rendering-intent", "resize",
"rest", "rest-after", "rest-before", "richness", "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", "ruby-position",
"ruby-span", "size", "speak", "speak-header", "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", "table-layout",
"target", "target-name", "target-new", "target-position", "text-align", "text-align-last", "text-decoration", "text-emphasis",
"text-height", "text-indent", "text-justify", "text-outline", "text-shadow", "text-transform", "text-wrap", "top", "transform",
"transform-origin", "transform-style", "transition", "transition-delay", "transition-duration", "transition-property",
"transition-timing-function", "unicode-bidi", "vertical-align", "visibility", "voice-balance", "voice-duration", "voice-family",
"voice-pitch", "voice-pitch-range", "voice-rate", "voice-stress", "voice-volume", "volume", "white-space", "white-space-collapse",
"widows", "width", "word-break", "word-spacing", "word-wrap", "z-index"
];
// Scanner constants

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Cedric Vivier <cedricv@neonux.com> (original author)
* Paul Rouget <paul@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -232,9 +233,6 @@ SplitView.prototype = {
* string and will be hidden.
* - object data
* Object to pass to the callbacks above.
* - boolean disableAnimations
* If true there is no animation or scrolling when this item is
* appended. Set this when batch appending (eg. initial population).
* - number ordinal
* Items with a lower ordinal are displayed before those with a
* higher ordinal.
@ -247,10 +245,6 @@ SplitView.prototype = {
binding._details = aDetails;
aSummary.setUserData(BINDING_USERDATA, binding, null);
if (!binding.disableAnimations) {
aSummary.classList.add("splitview-slide");
aSummary.classList.add("splitview-flash");
}
this._nav.appendChild(aSummary);
aSummary.addEventListener("click", function onSummaryClick(aEvent) {
@ -266,11 +260,6 @@ SplitView.prototype = {
binding.onCreate(aSummary, aDetails, binding.data);
}, 0);
}
if (!binding.disableAnimations) {
scheduleAnimation(aSummary, "splitview-slide", "splitview-flash");
aSummary.scrollIntoView();
}
},
/**
@ -462,28 +451,3 @@ SplitView.prototype = {
}
}
};
//
// private helpers
/**
* Schedule one or multiple CSS animation(s) on an element.
*
* @param DOMElement aElement
* @param string ...
* One or multiple animation class name(s).
*/
function scheduleAnimation(aElement)
{
let classes = Array.prototype.slice.call(arguments, 1);
for each (let klass in classes) {
aElement.classList.add(klass);
}
let window = aElement.ownerDocument.defaultView;
window.mozRequestAnimationFrame(function triggerAnimation() {
for each (let klass in classes) {
aElement.classList.remove(klass);
}
});
}

View File

@ -351,7 +351,7 @@ StyleEditorChrome.prototype = {
*/
_disableChrome: function SEC__disableChrome()
{
let matches = this._root.querySelectorAll("button,input,select");
let matches = this._root.querySelectorAll("button,toolbarbutton,textbox");
for (let i = 0; i < matches.length; ++i) {
matches[i].setAttribute("disabled", "disabled");
}

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Cedric Vivier <cedricv@neonux.com> (original author)
* Paul Rouget <paul@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -41,17 +42,24 @@ box,
-moz-box-orient: vertical;
}
.splitview-nav-container {
-moz-box-pack: center;
}
.splitview-controller,
.splitview-main {
-moz-box-flex: 0;
}
.splitview-controller {
min-height: 8em;
min-height: 3em;
max-height: 14em;
}
.splitview-nav {
display: -moz-box;
overflow-x: hidden;
overflow-y: auto;
}
/* only the active details pane is shown */
@ -62,13 +70,16 @@ box,
display: -moz-box;
}
.splitview-landscape-resizer {
cursor: ew-resize;
}
/* this is to keep in sync with SplitView.jsm's LANDSCAPE_MEDIA_QUERY */
@media (min-aspect-ratio: 5/3) {
.splitview-root {
-moz-box-orient: horizontal;
}
.splitview-controller {
-moz-box-flex: 0;
max-height: none;
}
.splitview-details {
@ -94,3 +105,18 @@ ol.splitview-nav > li.splitview-filtered {
.splitview-nav:empty ~ .splitview-nav.placeholder.empty {
display: -moz-box;
}
.splitview-portrait-resizer {
display: none;
}
/* portrait mode */
@media (max-aspect-ratio: 5/3) {
#splitview-details-toolbar {
display: none;
}
.splitview-portrait-resizer {
display: -moz-box;
}
}

View File

@ -35,9 +35,85 @@
*
* ***** END LICENSE BLOCK ***** */
.splitview-nav > li hgroup > .stylesheet-error-message {
.stylesheet-error-message {
display: none;
}
.splitview-nav > li.error hgroup > .stylesheet-error-message {
li.error > .stylesheet-info > .stylesheet-more > .stylesheet-error-message {
display: block;
}
.splitview-nav > li,
.stylesheet-info,
.stylesheet-more {
display: -moz-box;
}
.splitview-nav > li {
-moz-box-orient: horizontal;
}
.splitview-nav > li > hgroup {
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-flex: 1;
}
.stylesheet-info > h1 {
-moz-box-flex: 1;
}
.stylesheet-name {
/* clip the text at the beginning */
display: -moz-box;
direction: rtl;
text-align: left;
overflow: hidden;
}
.splitview-nav > li > hgroup.stylesheet-info {
-moz-box-pack: center;
}
.splitview-nav:-moz-locale-dir(ltr) > li.unsaved > hgroup .stylesheet-name:before,
.splitview-nav:-moz-locale-dir(rtl) > li.unsaved > hgroup .stylesheet-name:after {
content: "* ";
}
.stylesheet-enabled {
display: -moz-box;
}
.stylesheet-saveButton {
display: none;
}
.stylesheet-rule-count,
li:hover > hgroup > .stylesheet-more > h3 > .stylesheet-saveButton {
display: -moz-box;
}
.stylesheet-more > spacer {
-moz-box-flex: 1;
}
/* portrait mode */
@media (max-aspect-ratio: 5/3) {
li:hover > hgroup > .stylesheet-more > .stylesheet-rule-count {
display: none;
}
.stylesheet-more {
-moz-box-flex: 1;
-moz-box-direction: reverse;
}
.splitview-nav > li > hgroup.stylesheet-info {
-moz-box-orient: horizontal;
-moz-box-flex: 1;
}
.stylesheet-more > spacer {
-moz-box-flex: 0;
}
}

View File

@ -20,6 +20,7 @@
-
- Contributor(s):
- Cedric Vivier <cedricv@neonux.com> (original author)
- Paul Rouget <paul@mozilla.com>
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
@ -40,6 +41,7 @@
]>
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/splitview.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/devtools/common.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/devtools/splitview.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/styleeditor.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/devtools/styleeditor.css" type="text/css"?>
@ -53,24 +55,23 @@
<xul:script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
<xul:box id="style-editor-chrome" class="splitview-root">
<xul:box class="splitview-side-details"></xul:box>
<xul:box class="splitview-controller">
<xul:box class="splitview-controller" id="stylesheets-controller" persist="width height">
<xul:box class="splitview-main">
<xul:box class="toolbar">
<xul:button class="style-editor-newButton"
<xul:toolbar class="devtools-toolbar">
<xul:toolbarbutton class="style-editor-newButton devtools-toolbarbutton"
accesskey="&newButton.accesskey;"
tooltiptext="&newButton.tooltip;"
label="&newButton.label;"></xul:button>
<xul:button class="style-editor-importButton"
label="&newButton.label;"/>
<xul:toolbarbutton class="style-editor-importButton devtools-toolbarbutton"
accesskey="&importButton.accesskey;"
tooltiptext="&importButton.tooltip;"
label="&importButton.label;"></xul:button>
<xul:box class="spacer" flex="1"></xul:box>
<xul:textbox class="splitview-filter"
type="search"
label="&importButton.label;"/>
<xul:spacer flex="1"/>
<xul:textbox class="splitview-filter devtools-searchinput"
type="search" flex="1"
tooltiptext="&searchInput.tooltip;"
placeholder="&searchInput.placeholder;"/>
</xul:box>
</xul:toolbar>
</xul:box>
<xul:box class="splitview-nav-container">
<ol class="splitview-nav" tabindex="0"></ol>
@ -90,6 +91,7 @@
</div>
</xul:box> <!-- .splitview-nav-container -->
</xul:box> <!-- .splitview-controller -->
<xul:box class="splitview-side-details"/>
<div id="splitview-templates" hidden="true">
<li id="splitview-tpl-summary-stylesheet" tabindex="0">
@ -98,24 +100,29 @@
accesskey="&saveButton.accesskey;"></a>
<hgroup class="stylesheet-info">
<h1><a class="stylesheet-name" href="#"></a></h1>
<h2 class="stylesheet-title"></h2>
<h3 class="stylesheet-error-message"></h3>
</hgroup>
<div class="stylesheet-more">
<hgroup class="stylesheet-stats">
<div class="stylesheet-more">
<h3 class="stylesheet-title"></h3>
<h3 class="stylesheet-rule-count"></h3>
</hgroup>
<hgroup class="stylesheet-actions">
<h1><a class="stylesheet-saveButton" href="#"
<h3 class="stylesheet-error-message"></h3>
<xul:spacer/>
<h3><a class="stylesheet-saveButton" href="#"
title="&saveButton.tooltip;"
accesskey="&saveButton.accesskey;">&saveButton.label;</a></h1>
</hgroup>
</div>
accesskey="&saveButton.accesskey;">&saveButton.label;</a></h3>
</div>
</hgroup>
</li>
<xul:box id="splitview-tpl-details-stylesheet" class="splitview-details">
<div class="stylesheet-editor-input textbox"
data-placeholder="&editorTextbox.placeholder;"></div>
<xul:resizer class="splitview-portrait-resizer"
dir="bottom"
element="stylesheets-controller"/>
<xul:toolbar id="splitview-details-toolbar" class="devtools-toolbar">
<xul:resizer class="splitview-landscape-resizer"
dir="bottomend"
element="stylesheets-controller"/>
</xul:toolbar>
<xul:box class="stylesheet-editor-input textbox"
data-placeholder="&editorTextbox.placeholder;"/>
</xul:box>
</div> <!-- #splitview-templates -->
</xul:box> <!-- .splitview-root -->

View File

@ -51,7 +51,7 @@ function run(aChrome)
let elements;
disabledCount = 0;
elements = document.querySelectorAll("button,input,select");
elements = document.querySelectorAll("button,toolbarbutton,textbox");
for (let i = 0; i < elements.length; ++i) {
if (elements[i].hasAttribute("disabled")) {
disabledCount++;

View File

@ -4,13 +4,13 @@
*/
window.addEventListener("load", function () {
var ws1 = new MozWebSocket("ws://0.0.0.0:81");
var ws1 = new WebSocket("ws://0.0.0.0:81");
ws1.onopen = function() {
ws1.send("test 1");
ws1.close();
};
var ws2 = new window.frames[0].MozWebSocket("ws://0.0.0.0:82");
var ws2 = new window.frames[0].WebSocket("ws://0.0.0.0:82");
ws2.onopen = function() {
ws2.send("test 2");
ws2.close();

View File

@ -30,6 +30,8 @@
<!ENTITY engine.passwords.accesskey "P">
<!ENTITY engine.prefs.label "Preferences">
<!ENTITY engine.prefs.accesskey "S">
<!ENTITY engine.addons.label "Add-ons">
<!ENTITY engine.addons.accesskey "A">
<!-- Device Settings -->
<!ENTITY syncComputerName.label "Computer Name:">

View File

@ -2,7 +2,7 @@
<!-- First page of the wizard -->
<!ENTITY setup.pickSetupType.description "Welcome, if you've never used &syncBrand.fullName.label; before, you will need to create a new account.">
<!ENTITY setup.pickSetupType.description2 "Welcome! If you've never used &syncBrand.fullName.label; before, you will need to create a new account.">
<!ENTITY button.createNewAccount.label "Create a New Account">
<!ENTITY button.haveAccount.label "I Have an Account">
@ -88,6 +88,8 @@
<!ENTITY engine.passwords.accesskey "P">
<!ENTITY engine.prefs.label "Preferences">
<!ENTITY engine.prefs.accesskey "S">
<!ENTITY engine.addons.label "Add-ons">
<!ENTITY engine.addons.accesskey "A">
<!ENTITY choice2.merge.main.label "Merge this computer's data with my &syncBrand.shortName.label; data">
<!ENTITY choice2.merge.recommended.label "Recommended:">

View File

@ -1983,11 +1983,7 @@ panel[dimmed="true"] {
/* Highlighter toolbar */
#inspector-toolbar {
-moz-appearance: none;
padding: 4px 3px;
border-top: 1px solid hsla(210, 8%, 5%, .65);
box-shadow: 0 1px 0 0 hsla(210, 16%, 76%, .2) inset;
background-image: -moz-linear-gradient(top, hsl(210,11%,36%), hsl(210,11%,18%));
}
#inspector-toolbar[treepanel-open] {
@ -1995,13 +1991,6 @@ panel[dimmed="true"] {
-moz-padding-end: 0;
}
#devtools-sidebar-toolbar {
-moz-appearance: none;
padding: 4px 3px;
box-shadow: 0 1px 0 0 hsla(210, 16%, 76%, .2) inset;
background-image: -moz-linear-gradient(top, hsl(210,11%,36%), hsl(210,11%,18%));
}
#devtools-side-splitter {
-moz-appearance: none;
border: 0;
@ -2013,50 +2002,6 @@ panel[dimmed="true"] {
position: relative;
}
#inspector-inspect-toolbutton,
#inspector-tools > toolbarbutton,
#devtools-sidebar-toolbar > toolbarbutton {
-moz-appearance: none;
min-width: 78px;
min-height: 22px;
color: hsl(210,30%,85%);
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
border: 1px solid hsla(210,8%,5%,.45);
border-radius: 3px;
background: -moz-linear-gradient(hsla(212,7%,57%,.35), hsla(212,7%,57%,.1)) padding-box;
box-shadow: 0 1px 0 hsla(210,16%,76%,.15) inset, 0 0 0 1px hsla(210,16%,76%,.15) inset, 0 1px 0 hsla(210,16%,76%,.15);
margin: 0 3px;
}
#inspector-inspect-toolbutton:not([checked]):hover:active,
#inspector-tools > toolbarbutton:not([checked]):hover:active,
#devtools-sidebar-toolbar > toolbarbutton:not([checked]):hover:active {
border-color: hsla(210,8%,5%,.6);
background: -moz-linear-gradient(hsla(220,6%,10%,.3), hsla(212,7%,57%,.15) 65%, hsla(212,7%,57%,.3));
box-shadow: 0 0 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
}
#inspector-inspect-toolbutton[checked],
#inspector-tools > toolbarbutton[checked],
#devtools-sidebar-toolbar > toolbarbutton[checked] {
color: hsl(208,100%,60%) !important;
border-color: hsla(210,8%,5%,.6) !important;
background: -moz-linear-gradient(hsla(220,6%,10%,.6), hsla(210,11%,18%,.45) 75%, hsla(210,11%,30%,.4));
box-shadow: 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
}
#inspector-inspect-toolbutton[checked]:hover,
#inspector-tools > toolbarbutton[checked]:hover,
#devtools-sidebar-toolbar > toolbarbutton[checked]:hover {
background-color: transparent !important;
}
#inspector-inspect-toolbutton[checked]:hover:active,
#inspector-tools > toolbarbutton[checked]:hover:active,
#devtools-sidebar-toolbar > toolbarbutton[checked]:hover:active {
background-color: hsla(210,8%,5%,.2) !important;
}
/* Highlighter - toolbar resizers */
.inspector-resizer {

View File

@ -0,0 +1,112 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* ***** 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 DevTools code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Paul Rouget <paul@mozilla.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* Toolbar and Toolbar items */
.devtools-toolbar {
-moz-appearance: none;
padding: 4px 3px;
box-shadow: 0 1px 0 0 hsla(210, 16%, 76%, .2) inset;
background: -moz-linear-gradient(top, hsl(210,11%,36%), hsl(210,11%,18%));
}
.devtools-toolbarbutton {
-moz-appearance: none;
min-width: 78px;
min-height: 22px;
color: hsl(210,30%,85%);
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
border: 1px solid hsla(210,8%,5%,.45);
border-radius: 3px;
background: -moz-linear-gradient(hsla(212,7%,57%,.35), hsla(212,7%,57%,.1)) padding-box;
box-shadow: 0 1px 0 hsla(210,16%,76%,.15) inset, 0 0 0 1px hsla(210,16%,76%,.15) inset, 0 1px 0 hsla(210,16%,76%,.15);
margin: 0 3px;
}
.devtools-toolbarbutton:not([checked]):hover:active {
border-color: hsla(210,8%,5%,.6);
background: -moz-linear-gradient(hsla(220,6%,10%,.3), hsla(212,7%,57%,.15) 65%, hsla(212,7%,57%,.3));
box-shadow: 0 0 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
}
.devtools-toolbarbutton[checked] {
color: hsl(208,100%,60%) !important;
border-color: hsla(210,8%,5%,.6) !important;
background: -moz-linear-gradient(hsla(220,6%,10%,.6), hsla(210,11%,18%,.45) 75%, hsla(210,11%,30%,.4));
box-shadow: 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
}
.devtools-toolbarbutton[checked]:hover {
background-color: transparent !important;
}
.devtools-toolbarbutton[checked]:hover:active {
background-color: hsla(210,8%,5%,.2) !important;
}
/* Search input */
.devtools-searchinput {
-moz-appearance: none;
margin: 0 3px;
background-color: transparent;
border: 1px solid hsla(210,8%,5%,.6);
border-radius: 20px;
background-image: url(magnifying-glass.png), -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
background-repeat: no-repeat;
background-position: 4px 3px, top left, top left;
padding-top: 0;
padding-bottom: 0;
-moz-padding-start: 18px;
-moz-padding-end: 12px;
box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
0 0 0 1px hsla(210,16%,76%,.1) inset,
0 1px 0 hsla(210,16%,76%,.15);
color: hsl(210,30%,85%);
}
.devtools-searchinput:-moz-locale-dir(rtl) {
background-position: -moz-calc(100% - 4px) 3px, top left, top left;
}
.devtools-searchinput > .textbox-input-box > .textbox-search-icons {
display: none;
}
.devtools-searchinput > .textbox-input-box > .textbox-input:-moz-placeholder {
color: hsl(208,10%,66%);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 784 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Cedric Vivier <cedricv@neonux.com> (original author)
* Paul Rouget <paul@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -35,90 +36,124 @@
*
* ***** END LICENSE BLOCK ***** */
.splitview-root {
margin-top: 4px;
}
.splitview-filter {
-moz-box-flex: 1;
-moz-margin-start: 1ex;
max-width: 25ex;
}
.splitview-nav-container {
-moz-box-pack: center;
margin: 4px;
border: 1px inset WindowFrame;
border-radius: 4px;
background-color: -moz-default-background-color;
color: -moz-default-color;
background-color: hsl(208,11%,27%);
color: white;
}
ol.splitview-nav {
overflow-x: hidden;
overflow-y: auto;
.splitview-nav {
-moz-appearance: none;
margin: 0;
box-shadow: inset -1px 0 0 #222426;
}
.splitview-nav > li {
color: white;
background-clip: padding-box;
border-bottom: 1px solid hsla(210,16%,76%,.1);
box-shadow: inset 0 -1px 0 hsla(210,8%,5%,.25);
-moz-padding-end: 8px;
-moz-box-align: center;
}
.splitview-nav {
list-style-image: none;
list-style: none;
padding: 0;
margin: 0;
}
ol.splitview-nav > li {
display: -moz-box;
-moz-box-orient: vertical;
.splitview-nav > li {
outline: 0;
border-bottom: 1px solid ThreeDShadow;
padding: 2px;
padding-top: 4px;
vertical-align: bottom;
color: black;
-moz-transition-property: background-color, max-height;
-moz-transition-duration: 1s;
max-height: 2048px; /* for slide transition */
}
ol.splitview-nav > li.splitview-active {
background-color: #eaf2fe; /* same as orion.css's .line_caret */
}
ol.splitview-nav > li:hover,
ol.splitview-nav > li:focus {
background-color: #f0f5fd; /* slightly lighter .line_caret */
}
ol.splitview-nav > li.splitview-flash {
background-color: #faf0e1; /* complement of .line_caret */
}
ol.splitview-nav > li.splitview-slide {
max-height: 0;
overflow: hidden;
}
.splitview-side-details {
margin: 2px;
}
.splitview-nav.splitview-all-filtered ~ .splitview-nav.placeholder.all-filtered,
.splitview-nav:empty ~ .splitview-nav.placeholder.empty {
-moz-box-flex: 0;
.placeholder {
-moz-box-flex: 1;
-moz-box-back: center;
text-align: center;
}
.splitview-main .toolbar,
.splitview-main .toolbar > * {
display: -moz-box;
}
.splitview-main .toolbar {
-moz-box-flex: 1;
-moz-box-orient: horizontal;
-moz-padding-start: 3px;
.splitview-nav > li.splitview-active {
background-image: url(itemArrow-ltr.png),
-moz-linear-gradient(left, black, black),
-moz-linear-gradient(hsl(206,61%,40%), hsl(206,61%,31%));
background-repeat: no-repeat, no-repeat, repeat-x;
background-position: center right, top right, top left;
background-size: auto, 1px 100%, auto;
border-bottom: 1px solid hsla(210,8%,5%,.25);
box-shadow: inset 0 1px 0 hsla(210,40%,83%,.15),
inset 0 -1px 0 hsla(210,40%,83%,.05);
}
a {
color: -moz-hyperlinktext;
text-decoration: underline;
.splitview-nav > li.splitview-active:-moz-locale-dir(rtl) {
background-image: url(itemArrow-rtl.png),
-moz-linear-gradient(left, black, black),
-moz-linear-gradient(hsl(206,61%,40%), hsl(206,61%,31%));
background-repeat: no-repeat, no-repeat, repeat-x;
background-position: center left, top left, top right;
}
button {
margin: 0;
/* Toolbars */
.devtools-toolbar {
height: 26px;
background-origin: border-box;
background-clip: border-box;
border-top: 1px solid hsla(210,8%,5%,.5);
border-bottom: 1px solid hsla(210,8%,5%,.65);
padding: 3px;
}
.splitview-main > toolbar:-moz-locale-dir(ltr) {
border-right: 1px solid hsla(210,8%,5%,.5);
}
.splitview-main > toolbar:-moz-locale-dir(rtl) {
border-left: 1px solid hsla(210,8%,5%,.5);
}
.devtools-toolbarbutton {
font-size: 11px;
padding: 0 8px;
width: auto;
min-width: 48px;
min-height: 0;
}
/* Resizers */
.splitview-landscape-resizer {
-moz-appearance: none;
width: 7px;
background-image: -moz-linear-gradient(left, black 1px, rgba(255,255,255,0.2) 1px);
background-size: 2px 10px;
background-clip: padding-box;
background-repeat: repeat-x;
border-width: 1px;
border-style: solid;
border-color: rgba(255, 255, 255, 0.05);
margin: 5px 0;
-moz-transform: translateX(-7px);
}
.splitview-landscape-resizer:-moz-locale-dir(rtl) {
-moz-transform: translateX(7px);
}
.splitview-portrait-resizer {
-moz-appearance: none;
background: -moz-linear-gradient(top, black 1px, rgba(255,255,255,0.2) 1px),
-moz-linear-gradient(top, hsl(210,11%,36%), hsl(210,11%,18%));
height: 12px;
background-size: 10px 2px, 100% 12px;
background-clip: content-box, border-box;
background-repeat: repeat-y, no-repeat;
background-position: center center;
padding: 2px 0;
border-top: 1px solid hsla(210,8%,5%,.5);
border-bottom: 1px solid hsla(210,8%,5%,.5);
}
/* limited width mode (hide search unless it has focus [search-on-type]) */
@ -128,8 +163,6 @@ button {
position: fixed;
margin: 0;
bottom: -4em;
-moz-transition-property: bottom;
-moz-transition-duration: 0.2s;
}
.splitview-filter[focused="true"] {
bottom: 0;

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Cedric Vivier <cedricv@neonux.com> (original author)
* Paul Rouget <paul@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -35,136 +36,89 @@
*
* ***** END LICENSE BLOCK ***** */
ol.splitview-nav:focus {
.stylesheet-title,
.stylesheet-name {
text-decoration: none;
color: hsl(207,17%,88%);
}
.stylesheet-name {
font-size: 13px;
}
.stylesheet-rule-count,
.stylesheet-saveButton {
color: hsl(211,12%,60%);
}
.stylesheet-saveButton {
text-decoration: underline;
cursor: pointer;
}
.splitview-active .stylesheet-title,
.splitview-active .stylesheet-name {
color: hsl(0,0%,100%);
}
.splitview-active .stylesheet-rule-count,
.splitview-active .stylesheet-saveButton {
color: hsl(200,66%,70%);
}
.splitview-nav:focus {
outline: 0; /* focus ring is on the stylesheet name */
}
.splitview-nav > li:-moz-locale-dir(ltr),
.splitview-nav > li hgroup:-moz-locale-dir(ltr) {
float: left;
}
.splitview-nav > li:-moz-locale-dir(rtl),
.splitview-nav > li hgroup:-moz-locale-dir(rtl) {
float: right;
}
.splitview-nav > li > hgroup.stylesheet-info {
max-width: 66%;
}
.splitview-nav > li > hgroup .stylesheet-name {
display: inline-block;
width: 100%;
max-width: 34ex;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.splitview-nav > li.unsaved > hgroup .stylesheet-name {
font-style: italic;
}
.splitview-nav > li.unsaved > hgroup .stylesheet-name:before:-moz-locale-dir(ltr),
.splitview-nav > li.unsaved > hgroup .stylesheet-name:after:-moz-locale-dir(rtl) {
.splitview-nav:-moz-locale-dir(ltr) > li.unsaved > hgroup .stylesheet-name:before,
.splitview-nav:-moz-locale-dir(rtl) > li.unsaved > hgroup .stylesheet-name:after {
font-style: italic;
content: "* ";
}
.splitview-nav > li > .stylesheet-enabled {
float: left;
width: 20px;
height: 20px;
-moz-margin-end: 6px;
border: 1px solid transparent;
background-image: url(eye-toggle.png);
background-position: center center;
.stylesheet-enabled {
padding: 8px 0;
margin: 0 8px;
background-image: url(itemToggle.png);
background-repeat: no-repeat;
background-clip: content-box;
background-position: 0 8px;
width: 24px;
height: 40px;
}
.splitview-nav > li > .stylesheet-enabled:-moz-locale-dir(rtl) {
float: right;
}
.splitview-nav > li.disabled > .stylesheet-enabled {
background-image: none;
.disabled > .stylesheet-enabled {
background-position: -24px 8px;
}
.splitview-nav > li > .stylesheet-enabled:focus,
.splitview-nav > li:hover > .stylesheet-enabled {
outline: 0;
border: 1px inset WindowFrame;
-moz-margin-end: 6px;
}
.splitview-nav > li hgroup .stylesheet-title {
color: GrayText;
font-size: 0.8em;
}
.splitview-nav > li.error hgroup > .stylesheet-error-message {
.stylesheet-error-message {
color: red;
font-size: 0.8em;
}
.splitview-nav > li > .stylesheet-more {
position: relative;
right: 0;
}
.splitview-nav > li > .stylesheet-more:-moz-locale-dir(rtl) {
left: 0;
.stylesheet-more > h3 {
font-size: 11px;
-moz-margin-end: 2px;
}
.splitview-nav > li hgroup.stylesheet-stats,
.splitview-nav > li hgroup.stylesheet-actions {
position: absolute;
z-index: 2;
-moz-transition-property: left, right;
-moz-transition-duration: 0.2s;
-moz-transition-delay: 0.2s;
-moz-transition-timing-function: ease-in-out;
.devtools-searchinput {
max-width: 25ex;
font-size: 11px;
}
.splitview-nav > li hgroup.stylesheet-stats {
z-index: 1;
-moz-transition-delay: 0.4s;
color: GrayText;
padding-left: 6px; /* Fitts */
padding-right: 6px;
}
.splitview-nav > li hgroup.stylesheet-actions a {
color: ButtonText;
padding-left: 6px; /* Fitts */
padding-right: 6px;
.placeholder {
color: white;
}
.splitview-nav > li hgroup.stylesheet-actions:-moz-locale-dir(ltr),
.splitview-nav > li:hover hgroup.stylesheet-stats:-moz-locale-dir(ltr),
.splitview-nav > li:focus hgroup.stylesheet-stats:-moz-locale-dir(ltr),
.splitview-nav > li.splitview-active hgroup.stylesheet-stats:-moz-locale-dir(ltr) {
right: -50ex;
}
.splitview-nav > li hgroup.stylesheet-actions:-moz-locale-dir(rtl),
.splitview-nav > li:hover hgroup.stylesheet-stats:-moz-locale-dir(rtl),
.splitview-nav > li:focus hgroup.stylesheet-stats:-moz-locale-dir(rtl),
.splitview-nav > li.splitview-active hgroup.stylesheet-stats:-moz-locale-dir(rtl) {
left: -50ex;
}
.splitview-nav > li hgroup.stylesheet-stats:-moz-locale-dir(ltr),
.splitview-nav > li:hover hgroup.stylesheet-actions:-moz-locale-dir(ltr),
.splitview-nav > li:focus hgroup.stylesheet-actions:-moz-locale-dir(ltr),
.splitview-nav > li.splitview-active hgroup.stylesheet-actions:-moz-locale-dir(ltr) {
right: 0;
}
.splitview-nav > li hgroup.stylesheet-stats:-moz-locale-dir(rtl),
.splitview-nav > li:hover hgroup.stylesheet-actions:-moz-locale-dir(rtl),
.splitview-nav > li:focus hgroup.stylesheet-actions:-moz-locale-dir(rtl),
.splitview-nav > li.splitview-active hgroup.stylesheet-actions:-moz-locale-dir(rtl) {
left: 0;
}
.stylesheet-editor-input {
display: -moz-box;
-moz-box-flex: 1;
overflow: hidden;
min-height: 8em;
margin: 3px;
margin-top: 0;
border: 1px inset WindowFrame;
border-radius: 4px;
background-color: -moz-default-background-color;
.placeholder a {
text-decoration: underline;
}
h1,
@ -175,3 +129,28 @@ h3 {
margin: 0;
padding: 0;
}
/* portrait mode */
@media (max-aspect-ratio: 5/3) {
.splitview-nav {
box-shadow: none;
}
.splitview-nav > li.splitview-active {
background-size: 0 0, 0 0, auto;
}
.stylesheet-enabled {
padding: 0;
background-position: 0 0;
height: 24px;
}
.disabled > .stylesheet-enabled {
background-position: -24px 0;
}
.splitview-nav > li > hgroup.stylesheet-info {
-moz-box-align: baseline;
}
}

View File

@ -82,6 +82,7 @@ browser.jar:
skin/classic/browser/tabview/stack-expander.png (tabview/stack-expander.png)
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/browser/devtools/common.css (devtools/common.css)
skin/classic/browser/devtools/arrows.png (devtools/arrows.png)
skin/classic/browser/devtools/goto-mdn.png (devtools/goto-mdn.png)
skin/classic/browser/devtools/csshtmltree.css (devtools/csshtmltree.css)
@ -115,7 +116,10 @@ browser.jar:
skin/classic/browser/devtools/breadcrumbs/rtl-start-selected.png (devtools/breadcrumbs/rtl-start-selected.png)
skin/classic/browser/devtools/splitview.css (devtools/splitview.css)
skin/classic/browser/devtools/styleeditor.css (devtools/styleeditor.css)
skin/classic/browser/devtools/eye-toggle.png (devtools/eye-toggle.png)
skin/classic/browser/devtools/magnifying-glass.png (devtools/magnifying-glass.png)
skin/classic/browser/devtools/itemToggle.png (devtools/itemToggle.png)
skin/classic/browser/devtools/itemArrow-rtl.png (devtools/itemArrow-rtl.png)
skin/classic/browser/devtools/itemArrow-ltr.png (devtools/itemArrow-ltr.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16-throbber.png
skin/classic/browser/sync-16.png

View File

@ -2722,10 +2722,7 @@ panel[dimmed="true"] {
/* Highlighter toolbar */
#inspector-toolbar {
-moz-appearance: none;
border-top: 1px solid hsla(210, 8%, 5%, .65);
box-shadow: 0 1px 0 0 hsla(210, 16%, 76%, .2) inset;
background-image: -moz-linear-gradient(top, hsl(210,11%,36%), hsl(210,11%,18%));
padding: 4px 16px 4px 0; /* use -moz-padding-end: 16px when/if bug 631729 gets fixed */
}
@ -2733,13 +2730,6 @@ panel[dimmed="true"] {
padding: 0 0 4px;
}
#devtools-sidebar-toolbar {
-moz-appearance: none;
padding: 4px 3px;
box-shadow: 0 1px 0 0 hsla(210, 16%, 76%, .2) inset;
background-image: -moz-linear-gradient(top, hsl(210,11%,36%), hsl(210,11%,18%));
}
#devtools-side-splitter {
background-image: none !important;
border: 0;
@ -2751,49 +2741,6 @@ panel[dimmed="true"] {
position: relative;
}
#inspector-inspect-toolbutton,
#inspector-tools > toolbarbutton,
#devtools-sidebar-toolbar > toolbarbutton {
-moz-appearance: none;
min-width: 78px;
min-height: 22px;
color: hsl(210,30%,85%);
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
border: 1px solid hsla(210,8%,5%,.45);
border-radius: @toolbarbuttonCornerRadius@;
background: -moz-linear-gradient(hsla(212,7%,57%,.35), hsla(212,7%,57%,.1)) padding-box;
box-shadow: 0 1px 0 hsla(210,16%,76%,.15) inset, 0 0 0 1px hsla(210,16%,76%,.15) inset, 0 1px 0 hsla(210,16%,76%,.15);
}
#inspector-inspect-toolbutton > .toolbarbutton-text ,
#inspector-tools > toolbarbutton > .toolbarbutton-text,
#devtools-sidebar-toolbar > toolbarbutton > .toolbarbutton-text {
margin: 1px 6px;
}
#inspector-inspect-toolbutton:not([checked]):hover:active,
#inspector-tools > toolbarbutton:not([checked]):hover:active,
#devtools-sidebar-toolbar > toolbarbutton:not([checked]):hover:active {
border-color: hsla(210,8%,5%,.6);
background: -moz-linear-gradient(hsla(220,6%,10%,.3), hsla(212,7%,57%,.15) 65%, hsla(212,7%,57%,.3));
box-shadow: 0 0 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
}
#inspector-inspect-toolbutton[checked],
#inspector-tools > toolbarbutton[checked],
#devtools-sidebar-toolbar > toolbarbutton[checked] {
color: hsl(208,100%,60%) !important;
border-color: hsla(210,8%,5%,.6);
background: -moz-linear-gradient(hsla(220,6%,10%,.6), hsla(210,11%,18%,.45) 75%, hsla(210,11%,30%,.4));
box-shadow: 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
}
#inspector-inspect-toolbutton[checked]:hover:active,
#inspector-tools > toolbarbutton[checked]:hover:active,
#devtools-sidebar-toolbar > toolbarbutton[checked]:hover:active {
background-color: hsla(210,8%,5%,.2);
}
/* Highlighter - toolbar resizers */
.inspector-resizer {

View File

@ -0,0 +1,113 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* ***** 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 DevTools code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Paul Rouget <paul@mozilla.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
%include ../shared.inc
/* Toolbar and Toolbar items */
.devtools-toolbar {
-moz-appearance: none;
padding: 4px 3px;
box-shadow: 0 1px 0 0 hsla(210, 16%, 76%, .2) inset;
background-image: -moz-linear-gradient(top, hsl(210,11%,36%), hsl(210,11%,18%));
}
.devtools-toolbarbutton {
-moz-appearance: none;
min-width: 78px;
min-height: 22px;
color: hsl(210,30%,85%);
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
border: 1px solid hsla(210,8%,5%,.45);
border-radius: @toolbarbuttonCornerRadius@;
background: -moz-linear-gradient(hsla(212,7%,57%,.35), hsla(212,7%,57%,.1)) padding-box;
box-shadow: 0 1px 0 hsla(210,16%,76%,.15) inset, 0 0 0 1px hsla(210,16%,76%,.15) inset, 0 1px 0 hsla(210,16%,76%,.15);
}
.devtools-toolbarbutton > .toolbarbutton-text {
margin: 1px 6px;
}
.devtools-toolbarbutton:not([checked]):hover:active {
border-color: hsla(210,8%,5%,.6);
background: -moz-linear-gradient(hsla(220,6%,10%,.3), hsla(212,7%,57%,.15) 65%, hsla(212,7%,57%,.3));
box-shadow: 0 0 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
}
.devtools-toolbarbutton[checked] {
color: hsl(208,100%,60%) !important;
border-color: hsla(210,8%,5%,.6);
background: -moz-linear-gradient(hsla(220,6%,10%,.6), hsla(210,11%,18%,.45) 75%, hsla(210,11%,30%,.4));
box-shadow: 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
}
.devtools-toolbarbutton[checked]:hover:active {
background-color: hsla(210,8%,5%,.2);
}
/* Search input */
.devtools-searchinput {
-moz-appearance: none;
margin: 0 3px;
background-color: transparent;
border: 1px solid hsla(210,8%,5%,.6);
border-radius: 20px;
background-image: url(magnifying-glass.png), -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
background-repeat: no-repeat;
background-position: 4px 3px, top left, top left;
padding-top: 0;
padding-bottom: 0;
-moz-padding-start: 18px;
-moz-padding-end: 12px;
box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
0 0 0 1px hsla(210,16%,76%,.1) inset,
0 1px 0 hsla(210,16%,76%,.15);
color: hsl(210,30%,85%);
}
.devtools-searchinput:-moz-locale-dir(rtl) {
background-position: -moz-calc(100% - 4px) 3px, top left, top left;
}
.devtools-searchinput > .textbox-input-box > .textbox-search-icons {
display: none;
}
.devtools-searchinput > .textbox-input-box > .textbox-input:-moz-placeholder {
color: hsl(208,10%,66%);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 784 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Cedric Vivier <cedricv@neonux.com> (original author)
* Paul Rouget <paul@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -35,90 +36,124 @@
*
* ***** END LICENSE BLOCK ***** */
.splitview-root {
margin-top: 4px;
}
.splitview-filter {
-moz-box-flex: 1;
-moz-margin-start: 1ex;
max-width: 25ex;
}
.splitview-nav-container {
-moz-box-pack: center;
margin: 4px;
border: 1px inset WindowFrame;
border-radius: 4px;
background-color: -moz-default-background-color;
color: -moz-default-color;
background-color: hsl(208,11%,27%);
color: white;
}
ol.splitview-nav {
overflow-x: hidden;
overflow-y: auto;
.splitview-nav {
-moz-appearance: none;
margin: 0;
box-shadow: inset -1px 0 0 #222426;
}
.splitview-nav > li {
color: white;
background-clip: padding-box;
border-bottom: 1px solid hsla(210,16%,76%,.1);
box-shadow: inset 0 -1px 0 hsla(210,8%,5%,.25);
-moz-padding-end: 8px;
-moz-box-align: center;
}
.splitview-nav {
list-style-image: none;
list-style: none;
padding: 0;
margin: 0;
}
ol.splitview-nav > li {
display: -moz-box;
-moz-box-orient: vertical;
.splitview-nav > li {
outline: 0;
border-bottom: 1px solid ThreeDShadow;
padding: 2px;
padding-top: 4px;
vertical-align: bottom;
color: black;
-moz-transition-property: background-color, max-height;
-moz-transition-duration: 1s;
max-height: 2048px; /* for slide transition */
}
ol.splitview-nav > li.splitview-active {
background-color: #eaf2fe; /* same as orion.css's .line_caret */
}
ol.splitview-nav > li:hover,
ol.splitview-nav > li:focus {
background-color: #f0f5fd; /* slightly lighter .line_caret */
}
ol.splitview-nav > li.splitview-flash {
background-color: #faf0e1; /* complement of .line_caret */
}
ol.splitview-nav > li.splitview-slide {
max-height: 0;
overflow: hidden;
}
.splitview-side-details {
margin: 2px;
}
.splitview-nav.splitview-all-filtered ~ .splitview-nav.placeholder.all-filtered,
.splitview-nav:empty ~ .splitview-nav.placeholder.empty {
-moz-box-flex: 0;
.placeholder {
-moz-box-flex: 1;
-moz-box-back: center;
text-align: center;
}
.splitview-main .toolbar,
.splitview-main .toolbar > * {
display: -moz-box;
}
.splitview-main .toolbar {
-moz-box-flex: 1;
-moz-box-orient: horizontal;
-moz-padding-start: 3px;
.splitview-nav > li.splitview-active {
background-image: url(itemArrow-ltr.png),
-moz-linear-gradient(left, black, black),
-moz-linear-gradient(hsl(206,61%,40%), hsl(206,61%,31%));
background-repeat: no-repeat, no-repeat, repeat-x;
background-position: center right, top right, top left;
background-size: auto, 1px 100%, auto;
border-bottom: 1px solid hsla(210,8%,5%,.25);
box-shadow: inset 0 1px 0 hsla(210,40%,83%,.15),
inset 0 -1px 0 hsla(210,40%,83%,.05);
}
a {
color: -moz-hyperlinktext;
text-decoration: underline;
.splitview-nav > li.splitview-active:-moz-locale-dir(rtl) {
background-image: url(itemArrow-rtl.png),
-moz-linear-gradient(left, black, black),
-moz-linear-gradient(hsl(206,61%,40%), hsl(206,61%,31%));
background-repeat: no-repeat, no-repeat, repeat-x;
background-position: center left, top left, top right;
}
button {
margin: 0;
/* Toolbars */
.devtools-toolbar {
height: 26px;
background-origin: border-box;
background-clip: border-box;
border-top: 1px solid hsla(210,8%,5%,.5);
border-bottom: 1px solid hsla(210,8%,5%,.65);
padding: 3px;
}
.splitview-main > toolbar:-moz-locale-dir(ltr) {
border-right: 1px solid hsla(210,8%,5%,.5);
}
.splitview-main > toolbar:-moz-locale-dir(rtl) {
border-left: 1px solid hsla(210,8%,5%,.5);
}
.devtools-toolbarbutton {
font-size: 11px;
padding: 0 8px;
width: auto;
min-width: 48px;
min-height: 0;
}
/* Resizers */
.splitview-landscape-resizer {
-moz-appearance: none;
width: 7px;
background-image: -moz-linear-gradient(left, black 1px, rgba(255,255,255,0.2) 1px);
background-size: 2px 10px;
background-clip: padding-box;
background-repeat: repeat-x;
border-width: 1px;
border-style: solid;
border-color: rgba(255, 255, 255, 0.05);
margin: 5px 0;
-moz-transform: translateX(-7px);
}
.splitview-landscape-resizer:-moz-locale-dir(rtl) {
-moz-transform: translateX(7px);
}
.splitview-portrait-resizer {
-moz-appearance: none;
background: -moz-linear-gradient(top, black 1px, rgba(255,255,255,0.2) 1px),
-moz-linear-gradient(top, hsl(210,11%,36%), hsl(210,11%,18%));
height: 12px;
background-size: 10px 2px, 100% 12px;
background-clip: content-box, border-box;
background-repeat: repeat-y, no-repeat;
background-position: center center;
padding: 2px 0;
border-top: 1px solid hsla(210,8%,5%,.5);
border-bottom: 1px solid hsla(210,8%,5%,.5);
}
/* limited width mode (hide search unless it has focus [search-on-type]) */
@ -128,8 +163,6 @@ button {
position: fixed;
margin: 0;
bottom: -4em;
-moz-transition-property: bottom;
-moz-transition-duration: 0.2s;
}
.splitview-filter[focused="true"] {
bottom: 0;

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Cedric Vivier <cedricv@neonux.com> (original author)
* Paul Rouget <paul@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -35,136 +36,89 @@
*
* ***** END LICENSE BLOCK ***** */
ol.splitview-nav:focus {
.stylesheet-title,
.stylesheet-name {
text-decoration: none;
color: hsl(207,17%,88%);
}
.stylesheet-name {
font-size: 13px;
}
.stylesheet-rule-count,
.stylesheet-saveButton {
color: hsl(211,12%,60%);
}
.stylesheet-saveButton {
text-decoration: underline;
cursor: pointer;
}
.splitview-active .stylesheet-title,
.splitview-active .stylesheet-name {
color: hsl(0,0%,100%);
}
.splitview-active .stylesheet-rule-count,
.splitview-active .stylesheet-saveButton {
color: hsl(200,66%,70%);
}
.splitview-nav:focus {
outline: 0; /* focus ring is on the stylesheet name */
}
.splitview-nav > li:-moz-locale-dir(ltr),
.splitview-nav > li hgroup:-moz-locale-dir(ltr) {
float: left;
}
.splitview-nav > li:-moz-locale-dir(rtl),
.splitview-nav > li hgroup:-moz-locale-dir(rtl) {
float: right;
}
.splitview-nav > li > hgroup.stylesheet-info {
max-width: 66%;
}
.splitview-nav > li > hgroup .stylesheet-name {
display: inline-block;
width: 100%;
max-width: 34ex;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.splitview-nav > li.unsaved > hgroup .stylesheet-name {
font-style: italic;
}
.splitview-nav > li.unsaved > hgroup .stylesheet-name:before:-moz-locale-dir(ltr),
.splitview-nav > li.unsaved > hgroup .stylesheet-name:after:-moz-locale-dir(rtl) {
.splitview-nav:-moz-locale-dir(ltr) > li.unsaved > hgroup .stylesheet-name:before,
.splitview-nav:-moz-locale-dir(rtl) > li.unsaved > hgroup .stylesheet-name:after {
font-style: italic;
content: "* ";
}
.splitview-nav > li > .stylesheet-enabled {
float: left;
width: 20px;
height: 20px;
-moz-margin-end: 6px;
border: 1px solid transparent;
background-image: url(eye-toggle.png);
background-position: center center;
.stylesheet-enabled {
padding: 8px 0;
margin: 0 8px;
background-image: url(itemToggle.png);
background-repeat: no-repeat;
background-clip: content-box;
background-position: 0 8px;
width: 24px;
height: 40px;
}
.splitview-nav > li > .stylesheet-enabled:-moz-locale-dir(rtl) {
float: right;
}
.splitview-nav > li.disabled > .stylesheet-enabled {
background-image: none;
.disabled > .stylesheet-enabled {
background-position: -24px 8px;
}
.splitview-nav > li > .stylesheet-enabled:focus,
.splitview-nav > li:hover > .stylesheet-enabled {
outline: 0;
border: 1px inset WindowFrame;
-moz-margin-end: 6px;
}
.splitview-nav > li hgroup .stylesheet-title {
color: GrayText;
font-size: 0.8em;
}
.splitview-nav > li.error hgroup > .stylesheet-error-message {
.stylesheet-error-message {
color: red;
font-size: 0.8em;
}
.splitview-nav > li > .stylesheet-more {
position: relative;
right: 0;
}
.splitview-nav > li > .stylesheet-more:-moz-locale-dir(rtl) {
left: 0;
.stylesheet-more > h3 {
font-size: 11px;
-moz-margin-end: 2px;
}
.splitview-nav > li hgroup.stylesheet-stats,
.splitview-nav > li hgroup.stylesheet-actions {
position: absolute;
z-index: 2;
-moz-transition-property: left, right;
-moz-transition-duration: 0.2s;
-moz-transition-delay: 0.2s;
-moz-transition-timing-function: ease-in-out;
.devtools-searchinput {
max-width: 25ex;
font-size: 11px;
}
.splitview-nav > li hgroup.stylesheet-stats {
z-index: 1;
-moz-transition-delay: 0.4s;
color: GrayText;
padding-left: 6px; /* Fitts */
padding-right: 6px;
}
.splitview-nav > li hgroup.stylesheet-actions a {
color: ButtonText;
padding-left: 6px; /* Fitts */
padding-right: 6px;
.placeholder {
color: white;
}
.splitview-nav > li hgroup.stylesheet-actions:-moz-locale-dir(ltr),
.splitview-nav > li:hover hgroup.stylesheet-stats:-moz-locale-dir(ltr),
.splitview-nav > li:focus hgroup.stylesheet-stats:-moz-locale-dir(ltr),
.splitview-nav > li.splitview-active hgroup.stylesheet-stats:-moz-locale-dir(ltr) {
right: -50ex;
}
.splitview-nav > li hgroup.stylesheet-actions:-moz-locale-dir(rtl),
.splitview-nav > li:hover hgroup.stylesheet-stats:-moz-locale-dir(rtl),
.splitview-nav > li:focus hgroup.stylesheet-stats:-moz-locale-dir(rtl),
.splitview-nav > li.splitview-active hgroup.stylesheet-stats:-moz-locale-dir(rtl) {
left: -50ex;
}
.splitview-nav > li hgroup.stylesheet-stats:-moz-locale-dir(ltr),
.splitview-nav > li:hover hgroup.stylesheet-actions:-moz-locale-dir(ltr),
.splitview-nav > li:focus hgroup.stylesheet-actions:-moz-locale-dir(ltr),
.splitview-nav > li.splitview-active hgroup.stylesheet-actions:-moz-locale-dir(ltr) {
right: 0;
}
.splitview-nav > li hgroup.stylesheet-stats:-moz-locale-dir(rtl),
.splitview-nav > li:hover hgroup.stylesheet-actions:-moz-locale-dir(rtl),
.splitview-nav > li:focus hgroup.stylesheet-actions:-moz-locale-dir(rtl),
.splitview-nav > li.splitview-active hgroup.stylesheet-actions:-moz-locale-dir(rtl) {
left: 0;
}
.stylesheet-editor-input {
display: -moz-box;
-moz-box-flex: 1;
overflow: hidden;
min-height: 8em;
margin: 3px;
margin-top: 0;
border: 1px inset WindowFrame;
border-radius: 4px;
background-color: -moz-default-background-color;
.placeholder a {
text-decoration: underline;
}
h1,
@ -175,3 +129,28 @@ h3 {
margin: 0;
padding: 0;
}
/* portrait mode */
@media (max-aspect-ratio: 5/3) {
.splitview-nav {
box-shadow: none;
}
.splitview-nav > li.splitview-active {
background-size: 0 0, 0 0, auto;
}
.stylesheet-enabled {
padding: 0;
background-position: 0 0;
height: 24px;
}
.disabled > .stylesheet-enabled {
background-position: -24px 0;
}
.splitview-nav > li > hgroup.stylesheet-info {
-moz-box-align: baseline;
}
}

View File

@ -121,6 +121,7 @@ browser.jar:
skin/classic/browser/tabview/stack-expander.png (tabview/stack-expander.png)
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
* skin/classic/browser/devtools/common.css (devtools/common.css)
skin/classic/browser/devtools/arrows.png (devtools/arrows.png)
skin/classic/browser/devtools/goto-mdn.png (devtools/goto-mdn.png)
skin/classic/browser/devtools/csshtmltree.css (devtools/csshtmltree.css)
@ -155,7 +156,10 @@ browser.jar:
skin/classic/browser/devtools/breadcrumbs/rtl-start-selected.png (devtools/breadcrumbs/rtl-start-selected.png)
skin/classic/browser/devtools/splitview.css (devtools/splitview.css)
skin/classic/browser/devtools/styleeditor.css (devtools/styleeditor.css)
skin/classic/browser/devtools/eye-toggle.png (devtools/eye-toggle.png)
skin/classic/browser/devtools/magnifying-glass.png (devtools/magnifying-glass.png)
skin/classic/browser/devtools/itemToggle.png (devtools/itemToggle.png)
skin/classic/browser/devtools/itemArrow-rtl.png (devtools/itemArrow-rtl.png)
skin/classic/browser/devtools/itemArrow-ltr.png (devtools/itemArrow-ltr.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-throbber.png
skin/classic/browser/sync-16.png

View File

@ -2660,11 +2660,7 @@ panel[dimmed="true"] {
/* Highlighter toolbar */
#inspector-toolbar {
-moz-appearance: none;
padding: 4px 3px;
border-top: 1px solid hsla(211,68%,6%,.65) !important;
box-shadow: 0 1px 0 hsla(209,29%,72%,.25) inset;
background-image: -moz-linear-gradient(top, hsl(209,18%,34%), hsl(210,24%,16%));
}
#inspector-toolbar[treepanel-open] {
@ -2672,13 +2668,6 @@ panel[dimmed="true"] {
-moz-padding-end: 0;
}
#devtools-sidebar-toolbar {
-moz-appearance: none;
padding: 4px 3px;
box-shadow: 0 1px 0 hsla(209,29%,72%,.25) inset;
background-image: -moz-linear-gradient(top, hsl(209,18%,34%), hsl(210,24%,16%));
}
#devtools-side-splitter {
border: 0;
-moz-border-start: 1px solid #242b33;
@ -2689,49 +2678,6 @@ panel[dimmed="true"] {
position: relative;
}
#inspector-inspect-toolbutton,
#inspector-tools > toolbarbutton,
#devtools-sidebar-toolbar > toolbarbutton {
-moz-appearance: none;
min-width: 78px;
min-height: 22px;
color: hsl(210,30%,85%);
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
border: 1px solid hsla(211,68%,6%,.5);
border-radius: 3px;
background: -moz-linear-gradient(hsla(209,13%,54%,.35), hsla(209,13%,54%,.1) 85%, hsla(209,13%,54%,.2)) padding-box;
box-shadow: 0 1px 0 hsla(209,29%,72%,.15) inset, 0 0 0 1px hsla(209,29%,72%,.1) inset, 0 0 0 1px hsla(209,29%,72%,.1), 0 1px 0 hsla(210,16%,76%,.1);
}
#inspector-inspect-toolbutton > .toolbarbutton-icon,
#inspector-tools > toolbarbutton > .toolbarbutton-icon,
#devtools-sidebar-toolbar > toolbarbutton > .toolbarbutton-icon {
margin: 0;
}
#inspector-inspect-toolbutton:not([checked]):hover:active,
#inspector-tools > toolbarbutton:not([checked]):hover:active,
#devtools-sidebar-toolbar > toolbarbutton:not([checked]):hover:active {
background-color: hsla(210,18%,9%,.1);
background-image: -moz-linear-gradient(hsla(209,13%,54%,.35), hsla(209,13%,54%,.1) 85%, hsla(209,13%,54%,.2));
box-shadow: 0 1px 3px hsla(211,68%,6%,.5) inset, 0 0 0 1px hsla(209,29%,72%,.1), 0 1px 0 hsla(210,16%,76%,.1);
}
#inspector-inspect-toolbutton[checked],
#inspector-tools > toolbarbutton[checked],
#devtools-sidebar-toolbar > toolbarbutton[checked] {
border-color: hsla(211,68%,6%,.6);
background: -moz-linear-gradient(hsla(211,68%,6%,.1), hsla(211,68%,6%,.2));
box-shadow: 0 1px 3px hsla(211,68%,6%,.5) inset, 0 0 0 1px hsla(209,29%,72%,.1), 0 1px 0 hsla(210,16%,76%,.1);
color: hsl(200,100%,60%) !important;
}
#inspector-inspect-toolbutton[checked]:hover:active,
#inspector-tools > toolbarbutton[checked]:hover:active,
#devtools-sidebar-toolbar > toolbarbutton[checked]:hover:active {
background-color: hsla(211,68%,6%,.2);
}
/* Highlighter - toolbar resizers */
.inspector-resizer {

View File

@ -0,0 +1,120 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* ***** 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 DevTools code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Paul Rouget <paul@mozilla.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* Toolbar and Toolbar items */
.devtools-toolbar {
-moz-appearance: none;
padding: 4px 3px;
box-shadow: 0 1px 0 hsla(209,29%,72%,.25) inset;
background-image: -moz-linear-gradient(top, hsl(209,18%,34%), hsl(210,24%,16%));
}
.devtools-toolbarbutton {
-moz-appearance: none;
min-width: 78px;
min-height: 22px;
color: hsl(210,30%,85%);
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
border: 1px solid hsla(211,68%,6%,.5);
border-radius: 3px;
background: -moz-linear-gradient(hsla(209,13%,54%,.35), hsla(209,13%,54%,.1) 85%, hsla(209,13%,54%,.2)) padding-box;
box-shadow: 0 1px 0 hsla(209,29%,72%,.15) inset, 0 0 0 1px hsla(209,29%,72%,.1) inset, 0 0 0 1px hsla(209,29%,72%,.1), 0 1px 0 hsla(210,16%,76%,.1);
-moz-margin-end: 3px;
}
.devtools-toolbarbutton > .toolbarbutton-icon {
margin: 0;
}
.devtools-toolbarbutton:not([checked]):hover:active {
background-color: hsla(210,18%,9%,.1);
background-image: -moz-linear-gradient(hsla(209,13%,54%,.35), hsla(209,13%,54%,.1) 85%, hsla(209,13%,54%,.2));
box-shadow: 0 1px 3px hsla(211,68%,6%,.5) inset, 0 0 0 1px hsla(209,29%,72%,.1), 0 1px 0 hsla(210,16%,76%,.1);
}
.devtools-toolbarbutton[checked] {
border-color: hsla(211,68%,6%,.6);
background: -moz-linear-gradient(hsla(211,68%,6%,.1), hsla(211,68%,6%,.2));
box-shadow: 0 1px 3px hsla(211,68%,6%,.5) inset, 0 0 0 1px hsla(209,29%,72%,.1), 0 1px 0 hsla(210,16%,76%,.1);
color: hsl(200,100%,60%) !important;
}
.devtools-toolbarbutton:[checked]:hover:active {
background-color: hsla(211,68%,6%,.2);
}
/* Search input */
.devtools-searchinput {
-moz-appearance: none;
margin: 0 3px;
border: 1px solid hsla(211,68%,6%,.6);
box-shadow: inset 0 1px 0 hsla(211,68%,6%,.05), 0 0 0 1px hsla(210,40%,83%,.1);
border-radius: 2px;
background-color: transparent;
background-image: url(magnifying-glass.png), -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
background-repeat: no-repeat;
background-position: 4px 3px, top left, top left;
padding-top: 0;
padding-bottom: 0;
-moz-padding-start: 18px;
-moz-padding-end: 12px;
color: hsl(210,30%,85%);
-moz-transition-property: background-color, border-color, box-shadow;
-moz-transition-duration: 150ms;
-moz-transition-timing-function: ease;
}
.devtools-searchinput[focused] {
border-color: hsl(200,70%,40%) hsl(200,75%,37%) hsl(200,80%,35%);
background-origin: padding-box;
background-clip: padding-box;
box-shadow: inset 0 0 0 1px hsla(211,68%,6%,.1);
}
.devtools-searchinput:-moz-locale-dir(rtl) {
background-position: -moz-calc(100% - 4px) 3px, top left, top left;
}
.devtools-searchinput > .textbox-input-box > .textbox-search-icons {
display: none;
}
.devtools-searchinput > .textbox-input-box > .textbox-input:-moz-placeholder {
color: hsl(208,10%,66%);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 784 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Cedric Vivier <cedricv@neonux.com> (original author)
* Paul Rouget <paul@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -35,90 +36,124 @@
*
* ***** END LICENSE BLOCK ***** */
.splitview-root {
margin-top: 4px;
}
.splitview-filter {
-moz-box-flex: 1;
-moz-margin-start: 1ex;
max-width: 25ex;
}
.splitview-nav-container {
-moz-box-pack: center;
margin: 4px;
border: 1px inset WindowFrame;
border-radius: 4px;
background-color: -moz-default-background-color;
color: -moz-default-color;
background-color: hsl(211,21%,26%);
color: white;
}
ol.splitview-nav {
overflow-x: hidden;
overflow-y: auto;
.splitview-nav {
-moz-appearance: none;
margin: 0;
box-shadow: inset -1px 0 0 #222426;
}
.splitview-nav > li {
color: white;
background-clip: padding-box;
border-bottom: 1px solid hsla(210,40%,83%,.1);
box-shadow: inset 0 -1px 0 hsla(211,68%,6%,.3);
-moz-padding-end: 8px;
-moz-box-align: center;
}
.splitview-nav {
list-style-image: none;
list-style: none;
padding: 0;
margin: 0;
}
ol.splitview-nav > li {
display: -moz-box;
-moz-box-orient: vertical;
.splitview-nav > li {
outline: 0;
border-bottom: 1px solid ThreeDShadow;
padding: 2px;
padding-top: 4px;
vertical-align: bottom;
color: black;
-moz-transition-property: background-color, max-height;
-moz-transition-duration: 1s;
max-height: 2048px; /* for slide transition */
}
ol.splitview-nav > li.splitview-active {
background-color: #eaf2fe; /* same as orion.css's .line_caret */
}
ol.splitview-nav > li:hover,
ol.splitview-nav > li:focus {
background-color: #f0f5fd; /* slightly lighter .line_caret */
}
ol.splitview-nav > li.splitview-flash {
background-color: #faf0e1; /* complement of .line_caret */
}
ol.splitview-nav > li.splitview-slide {
max-height: 0;
overflow: hidden;
}
.splitview-side-details {
margin: 2px;
}
.splitview-nav.splitview-all-filtered ~ .splitview-nav.placeholder.all-filtered,
.splitview-nav:empty ~ .splitview-nav.placeholder.empty {
-moz-box-flex: 0;
.placeholder {
-moz-box-flex: 1;
-moz-box-back: center;
text-align: center;
}
.splitview-main .toolbar,
.splitview-main .toolbar > * {
display: -moz-box;
}
.splitview-main .toolbar {
-moz-box-flex: 1;
-moz-box-orient: horizontal;
-moz-padding-start: 3px;
.splitview-nav > li.splitview-active {
background-image: url(itemArrow-ltr.png),
-moz-linear-gradient(left, black, black),
-moz-linear-gradient(hsl(200,100%,33%), hsl(200,100%,25%));
background-repeat: no-repeat, no-repeat, repeat-x;
background-position: center right, top right, top left;
background-size: auto, 1px 100%, auto;
border-bottom: 1px solid hsla(210,8%,5%,.25);
box-shadow: inset 0 1px 0 hsla(210,40%,83%,.15),
inset 0 -1px 0 hsla(210,40%,83%,.05);
}
a {
color: -moz-hyperlinktext;
text-decoration: underline;
.splitview-nav > li.splitview-active:-moz-locale-dir(rtl) {
background-image: url(itemArrow-rtl.png),
-moz-linear-gradient(left, black, black),
-moz-linear-gradient(hsl(200,100%,33%), hsl(200,100%,25%));
background-repeat: no-repeat, no-repeat, repeat-x;
background-position: center left, top left, top right;
}
button {
margin: 0;
/* Toolbars */
.devtools-toolbar {
height: 26px;
background-origin: border-box;
background-clip: border-box;
border-top: 1px solid hsla(210,8%,5%,.5);
border-bottom: 1px solid hsla(210,8%,5%,.65);
padding: 3px;
}
.splitview-main > toolbar:-moz-locale-dir(ltr) {
border-right: 1px solid hsla(210,8%,5%,.5);
}
.splitview-main > toolbar:-moz-locale-dir(rtl) {
border-left: 1px solid hsla(210,8%,5%,.5);
}
.devtools-toolbarbutton {
font-size: 11px;
padding: 0 8px;
width: auto;
min-width: 48px;
min-height: 0;
}
/* Resizers */
.splitview-landscape-resizer {
-moz-appearance: none;
width: 7px;
background-image: -moz-linear-gradient(left, black 1px, rgba(255,255,255,0.2) 1px);
background-size: 2px 10px;
background-clip: padding-box;
background-repeat: repeat-x;
border-width: 1px;
border-style: solid;
border-color: rgba(255, 255, 255, 0.05);
margin: 5px 0;
-moz-transform: translateX(-7px);
}
.splitview-landscape-resizer:-moz-locale-dir(rtl) {
-moz-transform: translateX(7px);
}
.splitview-portrait-resizer {
-moz-appearance: none;
background: -moz-linear-gradient(top, black 1px, rgba(255,255,255,0.2) 1px),
-moz-linear-gradient(top, hsl(209,18%,34%), hsl(210,24%,16%));
height: 12px;
background-size: 10px 2px, 100% 12px;
background-clip: content-box, border-box;
background-repeat: repeat-y, no-repeat;
background-position: center center;
padding: 2px 0;
border-top: 1px solid hsla(210,8%,5%,.5);
border-bottom: 1px solid hsla(210,8%,5%,.5);
}
/* limited width mode (hide search unless it has focus [search-on-type]) */
@ -128,8 +163,6 @@ button {
position: fixed;
margin: 0;
bottom: -4em;
-moz-transition-property: bottom;
-moz-transition-duration: 0.2s;
}
.splitview-filter[focused="true"] {
bottom: 0;

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Cedric Vivier <cedricv@neonux.com> (original author)
* Paul Rouget <paul@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -35,136 +36,89 @@
*
* ***** END LICENSE BLOCK ***** */
ol.splitview-nav:focus {
.stylesheet-title,
.stylesheet-name {
text-decoration: none;
color: hsl(210,30%,85%);
}
.stylesheet-name {
font-size: 13px;
}
.stylesheet-rule-count,
.stylesheet-saveButton {
color: hsl(210,16%,53%);
}
.stylesheet-saveButton {
text-decoration: underline;
cursor: pointer;
}
.splitview-active .stylesheet-title,
.splitview-active .stylesheet-name {
color: hsl(0,0%,100%);
}
.splitview-active .stylesheet-rule-count,
.splitview-active .stylesheet-saveButton {
color: hsl(205,50%,70%);
}
.splitview-nav:focus {
outline: 0; /* focus ring is on the stylesheet name */
}
.splitview-nav > li:-moz-locale-dir(ltr),
.splitview-nav > li hgroup:-moz-locale-dir(ltr) {
float: left;
}
.splitview-nav > li:-moz-locale-dir(rtl),
.splitview-nav > li hgroup:-moz-locale-dir(rtl) {
float: right;
}
.splitview-nav > li > hgroup.stylesheet-info {
max-width: 66%;
}
.splitview-nav > li > hgroup .stylesheet-name {
display: inline-block;
width: 100%;
max-width: 34ex;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.splitview-nav > li.unsaved > hgroup .stylesheet-name {
font-style: italic;
}
.splitview-nav > li.unsaved > hgroup .stylesheet-name:before:-moz-locale-dir(ltr),
.splitview-nav > li.unsaved > hgroup .stylesheet-name:after:-moz-locale-dir(rtl) {
.splitview-nav:-moz-locale-dir(ltr) > li.unsaved > hgroup .stylesheet-name:before,
.splitview-nav:-moz-locale-dir(rtl) > li.unsaved > hgroup .stylesheet-name:after {
font-style: italic;
content: "* ";
}
.splitview-nav > li > .stylesheet-enabled {
float: left;
width: 20px;
height: 20px;
-moz-margin-end: 6px;
border: 1px solid transparent;
background-image: url(eye-toggle.png);
background-position: center center;
.stylesheet-enabled {
padding: 8px 0;
margin: 0 8px;
background-image: url(itemToggle.png);
background-repeat: no-repeat;
background-clip: content-box;
background-position: 0 8px;
width: 24px;
height: 40px;
}
.splitview-nav > li > .stylesheet-enabled:-moz-locale-dir(rtl) {
float: right;
}
.splitview-nav > li.disabled > .stylesheet-enabled {
background-image: none;
.disabled > .stylesheet-enabled {
background-position: -24px 8px;
}
.splitview-nav > li > .stylesheet-enabled:focus,
.splitview-nav > li:hover > .stylesheet-enabled {
outline: 0;
border: 1px inset WindowFrame;
-moz-margin-end: 6px;
}
.splitview-nav > li hgroup .stylesheet-title {
color: GrayText;
font-size: 0.8em;
}
.splitview-nav > li.error hgroup > .stylesheet-error-message {
.stylesheet-error-message {
color: red;
font-size: 0.8em;
}
.splitview-nav > li > .stylesheet-more {
position: relative;
right: 0;
}
.splitview-nav > li > .stylesheet-more:-moz-locale-dir(rtl) {
left: 0;
.stylesheet-more > h3 {
font-size: 11px;
-moz-margin-end: 2px;
}
.splitview-nav > li hgroup.stylesheet-stats,
.splitview-nav > li hgroup.stylesheet-actions {
position: absolute;
z-index: 2;
-moz-transition-property: left, right;
-moz-transition-duration: 0.2s;
-moz-transition-delay: 0.2s;
-moz-transition-timing-function: ease-in-out;
.devtools-searchinput {
max-width: 25ex;
font-size: 11px;
}
.splitview-nav > li hgroup.stylesheet-stats {
z-index: 1;
-moz-transition-delay: 0.4s;
color: GrayText;
padding-left: 6px; /* Fitts */
padding-right: 6px;
}
.splitview-nav > li hgroup.stylesheet-actions a {
color: ButtonText;
padding-left: 6px; /* Fitts */
padding-right: 6px;
.placeholder {
color: white;
}
.splitview-nav > li hgroup.stylesheet-actions:-moz-locale-dir(ltr),
.splitview-nav > li:hover hgroup.stylesheet-stats:-moz-locale-dir(ltr),
.splitview-nav > li:focus hgroup.stylesheet-stats:-moz-locale-dir(ltr),
.splitview-nav > li.splitview-active hgroup.stylesheet-stats:-moz-locale-dir(ltr) {
right: -50ex;
}
.splitview-nav > li hgroup.stylesheet-actions:-moz-locale-dir(rtl),
.splitview-nav > li:hover hgroup.stylesheet-stats:-moz-locale-dir(rtl),
.splitview-nav > li:focus hgroup.stylesheet-stats:-moz-locale-dir(rtl),
.splitview-nav > li.splitview-active hgroup.stylesheet-stats:-moz-locale-dir(rtl) {
left: -50ex;
}
.splitview-nav > li hgroup.stylesheet-stats:-moz-locale-dir(ltr),
.splitview-nav > li:hover hgroup.stylesheet-actions:-moz-locale-dir(ltr),
.splitview-nav > li:focus hgroup.stylesheet-actions:-moz-locale-dir(ltr),
.splitview-nav > li.splitview-active hgroup.stylesheet-actions:-moz-locale-dir(ltr) {
right: 0;
}
.splitview-nav > li hgroup.stylesheet-stats:-moz-locale-dir(rtl),
.splitview-nav > li:hover hgroup.stylesheet-actions:-moz-locale-dir(rtl),
.splitview-nav > li:focus hgroup.stylesheet-actions:-moz-locale-dir(rtl),
.splitview-nav > li.splitview-active hgroup.stylesheet-actions:-moz-locale-dir(rtl) {
left: 0;
}
.stylesheet-editor-input {
display: -moz-box;
-moz-box-flex: 1;
overflow: hidden;
min-height: 8em;
margin: 3px;
margin-top: 0;
border: 1px inset WindowFrame;
border-radius: 4px;
background-color: -moz-default-background-color;
.placeholder a {
text-decoration: underline;
}
h1,
@ -175,3 +129,28 @@ h3 {
margin: 0;
padding: 0;
}
/* portrait mode */
@media (max-aspect-ratio: 5/3) {
.splitview-nav {
box-shadow: none;
}
.splitview-nav > li.splitview-active {
background-size: 0 0, 0 0, auto;
}
.stylesheet-enabled {
padding: 0;
background-position: 0 0;
height: 24px;
}
.disabled > .stylesheet-enabled {
background-position: -24px 0;
}
.splitview-nav > li > hgroup.stylesheet-info {
-moz-box-align: baseline;
}
}

View File

@ -105,6 +105,7 @@ browser.jar:
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
skin/classic/browser/tabview/tabview-inverted.png (tabview/tabview-inverted.png)
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/browser/devtools/common.css (devtools/common.css)
skin/classic/browser/devtools/arrows.png (devtools/arrows.png)
skin/classic/browser/devtools/goto-mdn.png (devtools/goto-mdn.png)
skin/classic/browser/devtools/csshtmltree.css (devtools/csshtmltree.css)
@ -139,7 +140,10 @@ browser.jar:
skin/classic/browser/devtools/breadcrumbs/rtl-start-selected.png (devtools/breadcrumbs/rtl-start-selected.png)
skin/classic/browser/devtools/splitview.css (devtools/splitview.css)
skin/classic/browser/devtools/styleeditor.css (devtools/styleeditor.css)
skin/classic/browser/devtools/eye-toggle.png (devtools/eye-toggle.png)
skin/classic/browser/devtools/magnifying-glass.png (devtools/magnifying-glass.png)
skin/classic/browser/devtools/itemToggle.png (devtools/itemToggle.png)
skin/classic/browser/devtools/itemArrow-rtl.png (devtools/itemArrow-rtl.png)
skin/classic/browser/devtools/itemArrow-ltr.png (devtools/itemArrow-ltr.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-throbber.png
skin/classic/browser/sync-16.png
@ -260,6 +264,7 @@ browser.jar:
skin/classic/aero/browser/tabview/tabview.png (tabview/tabview.png)
skin/classic/aero/browser/tabview/tabview-inverted.png (tabview/tabview-inverted.png)
skin/classic/aero/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/aero/browser/devtools/common.css (devtools/common.css)
skin/classic/aero/browser/devtools/arrows.png (devtools/arrows.png)
skin/classic/aero/browser/devtools/goto-mdn.png (devtools/goto-mdn.png)
skin/classic/aero/browser/devtools/csshtmltree.css (devtools/csshtmltree.css)
@ -294,7 +299,10 @@ browser.jar:
skin/classic/aero/browser/devtools/breadcrumbs/rtl-start-selected.png (devtools/breadcrumbs/rtl-start-selected.png)
skin/classic/aero/browser/devtools/splitview.css (devtools/splitview.css)
skin/classic/aero/browser/devtools/styleeditor.css (devtools/styleeditor.css)
skin/classic/aero/browser/devtools/eye-toggle.png (devtools/eye-toggle.png)
skin/classic/aero/browser/devtools/magnifying-glass.png (devtools/magnifying-glass.png)
skin/classic/aero/browser/devtools/itemToggle.png (devtools/itemToggle.png)
skin/classic/aero/browser/devtools/itemArrow-rtl.png (devtools/itemArrow-rtl.png)
skin/classic/aero/browser/devtools/itemArrow-ltr.png (devtools/itemArrow-ltr.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/aero/browser/sync-throbber.png
skin/classic/aero/browser/sync-16.png

View File

@ -117,7 +117,7 @@ XPIDLSRCS = \
nsIXMLHttpRequest.idl \
nsIContentSecurityPolicy.idl \
nsIFrameMessageManager.idl \
nsIMozWebSocket.idl \
nsIWebSocket.idl \
nsIEventSource.idl \
$(NULL)

View File

@ -134,10 +134,6 @@ protected:
return false;
}
indexedDB::FileInfo*
GetFileInfoInternal(indexedDB::FileManager* aFileManager,
PRUint32 aStartIndex);
bool mIsFile;
bool mImmutable;
nsString mContentType;

View File

@ -53,14 +53,14 @@ class nsString;
[ref] native nsStringTArrayRef(nsTArray<nsString>);
/**
* The nsIMozWebSocket interface enables Web applications to maintain
* The nsIWebSocket interface enables Web applications to maintain
* bidirectional communications with server-side processes as described in:
*
* http://dev.w3.org/html5/websockets/
*
*/
[scriptable, uuid(f463b9b5-1408-4057-9224-e4f5bc33f17b)]
interface nsIMozWebSocket : nsISupports
interface nsIWebSocket : nsISupports
{
readonly attribute DOMString url;
readonly attribute DOMString extensions;

View File

@ -168,8 +168,8 @@ nsWebSocket::CloseConnection()
// reference until the end of the method
nsRefPtr<nsWebSocket> kungfuDeathGrip = this;
if (mReadyState == nsIMozWebSocket::CONNECTING) {
SetReadyState(nsIMozWebSocket::CLOSED);
if (mReadyState == nsIWebSocket::CONNECTING) {
SetReadyState(nsIWebSocket::CLOSED);
if (mChannel) {
mChannel->Close(mClientReasonCode, mClientReason);
}
@ -177,10 +177,10 @@ nsWebSocket::CloseConnection()
return NS_OK;
}
SetReadyState(nsIMozWebSocket::CLOSING);
SetReadyState(nsIWebSocket::CLOSING);
if (mDisconnected) {
SetReadyState(nsIMozWebSocket::CLOSED);
SetReadyState(nsIWebSocket::CLOSED);
Disconnect();
return NS_OK;
}
@ -202,7 +202,7 @@ nsWebSocket::ConsoleError()
NS_ConvertUTF8toUTF16 specUTF16(targetSpec);
const PRUnichar *formatStrings[] = { specUTF16.get() };
if (mReadyState < nsIMozWebSocket::OPEN) {
if (mReadyState < nsIWebSocket::OPEN) {
PrintErrorOnConsole("chrome://global/locale/appstrings.properties",
NS_LITERAL_STRING("connectionFailure").get(),
formatStrings, ArrayLength(formatStrings));
@ -261,35 +261,39 @@ nsWebSocket::Disconnect()
// nsWebSocket::nsIWebSocketListener methods:
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsWebSocket::OnMessageAvailable(nsISupports *aContext, const nsACString & aMsg)
nsresult
nsWebSocket::DoOnMessageAvailable(const nsACString & aMsg, bool isBinary)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
NS_ABORT_IF_FALSE(!mDisconnected, "Received message after disconnecting");
// Dispatch New Message
nsresult rv = CreateAndDispatchMessageEvent(aMsg, false);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to dispatch the message event");
if (mReadyState == nsIWebSocket::OPEN) {
// Dispatch New Message
nsresult rv = CreateAndDispatchMessageEvent(aMsg, isBinary);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to dispatch the message event");
}
} else {
// CLOSING should be the only other state where it's possible to get msgs
// from channel: Spec says to drop them.
NS_ASSERTION(mReadyState == nsIWebSocket::CLOSING,
"Received message while CONNECTING or CLOSED");
}
return NS_OK;
}
NS_IMETHODIMP
nsWebSocket::OnMessageAvailable(nsISupports *aContext, const nsACString & aMsg)
{
return DoOnMessageAvailable(aMsg, false);
}
NS_IMETHODIMP
nsWebSocket::OnBinaryMessageAvailable(nsISupports *aContext,
const nsACString & aMsg)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
NS_ABORT_IF_FALSE(!mDisconnected, "Received message after disconnecting");
// Dispatch New Message
nsresult rv = CreateAndDispatchMessageEvent(aMsg, true);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to dispatch the message event");
}
return NS_OK;
return DoOnMessageAvailable(aMsg, true);
}
NS_IMETHODIMP
@ -306,7 +310,7 @@ nsWebSocket::OnStart(nsISupports *aContext)
mChannel->GetExtensions(mEstablishedExtensions);
UpdateURI();
SetReadyState(nsIMozWebSocket::OPEN);
SetReadyState(nsIWebSocket::OPEN);
return NS_OK;
}
@ -320,7 +324,7 @@ nsWebSocket::OnStop(nsISupports *aContext, nsresult aStatusCode)
mClosedCleanly = NS_SUCCEEDED(aStatusCode);
if (aStatusCode == NS_BASE_STREAM_CLOSED &&
mReadyState >= nsIMozWebSocket::CLOSING) {
mReadyState >= nsIWebSocket::CLOSING) {
// don't generate an error event just because of an unclean close
aStatusCode = NS_OK;
}
@ -332,7 +336,7 @@ nsWebSocket::OnStop(nsISupports *aContext, nsresult aStatusCode)
NS_WARNING("Failed to dispatch the error event");
}
SetReadyState(nsIMozWebSocket::CLOSED);
SetReadyState(nsIWebSocket::CLOSED);
Disconnect();
return NS_OK;
@ -405,7 +409,7 @@ nsWebSocket::nsWebSocket() : mKeepingAlive(false),
mDisconnected(false),
mClientReasonCode(0),
mServerReasonCode(nsIWebSocketChannel::CLOSE_ABNORMAL),
mReadyState(nsIMozWebSocket::CONNECTING),
mReadyState(nsIWebSocket::CONNECTING),
mOutgoingBufferedAmount(0),
mBinaryType(WS_BINARY_TYPE_BLOB),
mScriptLine(0),
@ -448,15 +452,15 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsWebSocket,
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
DOMCI_DATA(MozWebSocket, nsWebSocket)
DOMCI_DATA(WebSocket, nsWebSocket)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsWebSocket)
NS_INTERFACE_MAP_ENTRY(nsIMozWebSocket)
NS_INTERFACE_MAP_ENTRY(nsIWebSocket)
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIWebSocketListener)
NS_INTERFACE_MAP_ENTRY(nsIRequest)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozWebSocket)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebSocket)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
NS_IMPL_ADDREF_INHERITED(nsWebSocket, nsDOMEventTargetWrapperCache)
@ -846,13 +850,13 @@ nsWebSocket::SetReadyState(PRUint16 aNewReadyState)
return;
}
NS_ABORT_IF_FALSE((aNewReadyState == nsIMozWebSocket::OPEN) ||
(aNewReadyState == nsIMozWebSocket::CLOSING) ||
(aNewReadyState == nsIMozWebSocket::CLOSED),
NS_ABORT_IF_FALSE((aNewReadyState == nsIWebSocket::OPEN) ||
(aNewReadyState == nsIWebSocket::CLOSING) ||
(aNewReadyState == nsIWebSocket::CLOSED),
"unexpected readyState");
if (aNewReadyState == nsIMozWebSocket::OPEN) {
NS_ABORT_IF_FALSE(mReadyState == nsIMozWebSocket::CONNECTING,
if (aNewReadyState == nsIWebSocket::OPEN) {
NS_ABORT_IF_FALSE(mReadyState == nsIWebSocket::CONNECTING,
"unexpected readyState transition");
mReadyState = aNewReadyState;
@ -864,15 +868,15 @@ nsWebSocket::SetReadyState(PRUint16 aNewReadyState)
return;
}
if (aNewReadyState == nsIMozWebSocket::CLOSING) {
NS_ABORT_IF_FALSE((mReadyState == nsIMozWebSocket::CONNECTING) ||
(mReadyState == nsIMozWebSocket::OPEN),
if (aNewReadyState == nsIWebSocket::CLOSING) {
NS_ABORT_IF_FALSE((mReadyState == nsIWebSocket::CONNECTING) ||
(mReadyState == nsIWebSocket::OPEN),
"unexpected readyState transition");
mReadyState = aNewReadyState;
return;
}
if (aNewReadyState == nsIMozWebSocket::CLOSED) {
if (aNewReadyState == nsIWebSocket::CLOSED) {
mReadyState = aNewReadyState;
// The close event must be dispatched asynchronously.
@ -989,7 +993,7 @@ nsWebSocket::UpdateMustKeepAlive()
if (mListenerManager) {
switch (mReadyState)
{
case nsIMozWebSocket::CONNECTING:
case nsIWebSocket::CONNECTING:
{
if (mListenerManager->HasListenersFor(NS_LITERAL_STRING("open")) ||
mListenerManager->HasListenersFor(NS_LITERAL_STRING("message")) ||
@ -1000,8 +1004,8 @@ nsWebSocket::UpdateMustKeepAlive()
}
break;
case nsIMozWebSocket::OPEN:
case nsIMozWebSocket::CLOSING:
case nsIWebSocket::OPEN:
case nsIWebSocket::CLOSING:
{
if (mListenerManager->HasListenersFor(NS_LITERAL_STRING("message")) ||
mListenerManager->HasListenersFor(NS_LITERAL_STRING("error")) ||
@ -1012,7 +1016,7 @@ nsWebSocket::UpdateMustKeepAlive()
}
break;
case nsIMozWebSocket::CLOSED:
case nsIWebSocket::CLOSED:
{
shouldKeepAlive =
(!mTriggeredCloseEvent &&
@ -1097,7 +1101,7 @@ nsWebSocket::AddEventListener(const nsAString& aType,
}
//-----------------------------------------------------------------------------
// nsWebSocket::nsIMozWebSocket methods:
// nsWebSocket::nsIWebSocket methods:
//-----------------------------------------------------------------------------
NS_IMETHODIMP
@ -1213,7 +1217,7 @@ nsWebSocket::Send(nsIVariant *aData)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
if (mReadyState == nsIMozWebSocket::CONNECTING) {
if (mReadyState == nsIWebSocket::CONNECTING) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
@ -1227,12 +1231,12 @@ nsWebSocket::Send(nsIVariant *aData)
// Always increment outgoing buffer len, even if closed
mOutgoingBufferedAmount += msgLen;
if (mReadyState == nsIMozWebSocket::CLOSING ||
mReadyState == nsIMozWebSocket::CLOSED) {
if (mReadyState == nsIWebSocket::CLOSING ||
mReadyState == nsIWebSocket::CLOSED) {
return NS_OK;
}
NS_ASSERTION(mReadyState == nsIMozWebSocket::OPEN,
NS_ASSERTION(mReadyState == nsIWebSocket::OPEN,
"Unknown state in nsWebSocket::Send");
if (msgStream) {
@ -1406,12 +1410,12 @@ nsWebSocket::Close(PRUint16 code, const nsAString & reason, PRUint8 argc)
if (argc >= 2)
mClientReason = utf8Reason;
if (mReadyState == nsIMozWebSocket::CLOSING ||
mReadyState == nsIMozWebSocket::CLOSED) {
if (mReadyState == nsIWebSocket::CLOSING ||
mReadyState == nsIWebSocket::CLOSED) {
return NS_OK;
}
if (mReadyState == nsIMozWebSocket::CONNECTING) {
if (mReadyState == nsIWebSocket::CONNECTING) {
// FailConnection() can release the object, so we keep a reference
// before calling it
nsRefPtr<nsWebSocket> kungfuDeathGrip = this;
@ -1420,7 +1424,7 @@ nsWebSocket::Close(PRUint16 code, const nsAString & reason, PRUint8 argc)
return NS_OK;
}
// mReadyState == nsIMozWebSocket::OPEN
// mReadyState == nsIWebSocket::OPEN
CloseConnection();
return NS_OK;

View File

@ -41,7 +41,7 @@
#define nsWebSocket_h__
#include "nsISupportsUtils.h"
#include "nsIMozWebSocket.h"
#include "nsIWebSocket.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIJSNativeInitializer.h"
@ -70,7 +70,7 @@ class nsWSCloseEvent;
class nsAutoCloseWS;
class nsWebSocket: public nsDOMEventTargetWrapperCache,
public nsIMozWebSocket,
public nsIWebSocket,
public nsIJSNativeInitializer,
public nsIInterfaceRequestor,
public nsIWebSocketListener,
@ -85,7 +85,7 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsWebSocket,
nsDOMEventTargetWrapperCache)
NS_DECL_NSIMOZWEBSOCKET
NS_DECL_NSIWEBSOCKET
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIWEBSOCKETLISTENER
NS_DECL_NSIREQUEST
@ -129,6 +129,7 @@ protected:
nsCOMPtr<nsIInputStream> &aStreamOut,
bool &aIsBinary, PRUint32 &aOutgoingLength);
nsresult DoOnMessageAvailable(const nsACString & aMsg, bool isBinary);
nsresult CreateAndDispatchSimpleEvent(const nsString& aName);
nsresult CreateAndDispatchMessageEvent(const nsACString& aData,
bool isBinary);

View File

@ -70,7 +70,13 @@ def web_socket_transfer_data(request):
msgutil.close_connection(request)
msgutil.send_message(request, "server data")
elif request.ws_protocol == "test-15":
msgutil.close_connection(request, True)
# DISABLED: close_connection hasn't supported 2nd 'abort' argument for a
# long time. Passing extra arg was causing exception, which conveniently
# caused abort :) but as of pywebsocket v606 raising an exception here no
# longer aborts, and there's no obvious way to close TCP connection w/o
# sending websocket CLOSE.
raise RuntimeError("test-15 should be disabled for now")
#msgutil.close_connection(request, True) # OBSOLETE 2nd arg
return
elif request.ws_protocol == "test-17" or request.ws_protocol == "test-21":
time.sleep(2)
@ -128,6 +134,8 @@ def web_socket_transfer_data(request):
msgutil.send_message(request, rcv, True, True)
else:
msgutil.send_message(request, "incorrect binary msg received: '" + rcv + "'")
elif request.ws_protocol == "test-46":
msgutil.send_message(request, "client must drop this if close was called")
while not request.client_terminated:
msgutil.receive_message(request)

View File

@ -43,8 +43,7 @@
* 21. see bug 572975 - same as test 17, but delete strong event listeners when
* receiving the message event;
* 22. server takes too long to establish the ws connection;
* 23. see bug 664692 - feature detection should detect MozWebSocket but not
* WebSocket on window object;
* 23. should detect WebSocket on window object;
* 24. server rejects sub-protocol string
* 25. ctor with valid empty sub-protocol array
* 26. ctor with invalid sub-protocol array containing 1 empty element
@ -69,10 +68,11 @@
* 43. Test setting binaryType attribute
* 44. Test sending/receving binary ArrayBuffer
* 45. Test sending/receving binary Blob
* 46. Test that we don't dispatch incoming msgs once in CLOSING state
*/
var first_test = 1;
var last_test = 45;
var last_test = 46;
var current_test = first_test;
@ -126,9 +126,9 @@ function CreateTestWS(ws_location, ws_protocol, no_increment_test)
try {
if (ws_protocol == undefined) {
ws = new MozWebSocket(ws_location);
ws = new WebSocket(ws_location);
} else {
ws = new MozWebSocket(ws_location, ws_protocol);
ws = new WebSocket(ws_location, ws_protocol);
}
@ -510,10 +510,14 @@ function test14()
ws.onclose = function(e)
{
shouldCloseCleanly(e);
doTest(15);
// Skip test 15 for now: broken
doTest(16);
};
}
/*
* DISABLED: see comments for test-15 case in file_websocket_wsh.py
*
function test15()
{
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-15");
@ -529,6 +533,7 @@ function test15()
}
}
*/
function test16()
{
@ -537,7 +542,6 @@ function test16()
{
ws.close();
ok(!ws.send("client data"), "shouldn't send message after calling close()");
doTest(17);
}
ws.onmessage = function()
{
@ -549,6 +553,7 @@ function test16()
}
ws.onclose = function()
{
doTest(17);
}
}
@ -560,7 +565,7 @@ window._test17 = function()
{
waitTest17 = true;
var local_ws = new MozWebSocket("ws://sub1.test2.example.org/tests/content/base/test/file_websocket", "test-17");
var local_ws = new WebSocket("ws://sub1.test2.example.org/tests/content/base/test/file_websocket", "test-17");
local_ws._testNumber = "local17";
local_ws._testNumber = current_test++;
@ -643,7 +648,7 @@ window._test20 = function()
{
waitTest20 = true;
var local_ws = new MozWebSocket("ws://sub1.test1.example.org/tests/content/base/test/file_websocket", "test-20");
var local_ws = new WebSocket("ws://sub1.test1.example.org/tests/content/base/test/file_websocket", "test-20");
local_ws._testNumber = "local20";
local_ws._testNumber = current_test++;
@ -678,7 +683,7 @@ window._test21 = function()
{
waitTest21 = true;
var local_ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-21");
var local_ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-21");
local_ws._testNumber = current_test++;
var received_message = false;
@ -753,8 +758,7 @@ function test22()
function test23()
{
current_test++;
is(false, "WebSocket" in window, "WebSocket shouldn't be available on window object");
is(true, "MozWebSocket" in window, "MozWebSocket should be available on window object");
is(true, "WebSocket" in window, "WebSocket should be available on window object");
doTest(24);
}
@ -1378,6 +1382,28 @@ function test45()
}
}
function test46()
{
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-46");
ok(ws.readyState == 0, "create bad readyState in test-46!");
ws.onopen = function()
{
ok(ws.readyState == 1, "open bad readyState in test-46!");
ws.close()
ok(ws.readyState == 2, "close must set readyState to 2 in test-46!");
}
ws.onmessage = function(e)
{
ok(false, "received message after calling close in test-46!");
}
ws.onclose = function(e)
{
ok(ws.readyState == 3, "onclose bad readyState in test-46!");
shouldCloseCleanly(e);
doTest(47);
}
}
var ranAllTests = false;
function maybeFinished()

View File

@ -31,7 +31,7 @@ function finishWSTest() {
function testWebSocket () {
var url = "ws://mochi.test:8888/tests/content/base/test/file_websocket_basic";
ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket_basic", "test");
ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket_basic", "test");
is(ws.url, url, "Wrong Websocket.url!");
ws.onopen = function(e) {
for (var i = 0; i < params.length; ++i) {
@ -56,7 +56,7 @@ function testWebSocket () {
}
function testWebSocket2() {
ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket_basic", "test");
ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket_basic", "test");
var testCount = 1000; // Send lots of messages
var messageCount = 0;
var testMessage = "test message";
@ -86,7 +86,7 @@ function testWebSocket2() {
}
function testWebSocket3() {
ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket_basic", "test");
ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket_basic", "test");
var testCount = 100; // Send lots of messages
var messageCount = 0;
var testMessage = "test message";
@ -118,7 +118,7 @@ function testWebSocket3() {
}
function testWebSocket4() {
ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket_basic", "test");
ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket_basic", "test");
// String length = (10,000 - 1) * 23 = 229,977 = almost 225 KiB.
var longString = new Array(10000).join("-huge websocket message");
ws.onopen = function(e) {
@ -145,7 +145,7 @@ function testWebSocket4() {
}
function testWebSocket5() {
ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket_basic", "test");
ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket_basic", "test");
ws.onopen = function(e) {
this.close();
}

View File

@ -18,7 +18,7 @@
var ws;
function testWebSocket () {
ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket_hello");
ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket_hello");
ws.onopen = function(e) {
ws.send("data");
}

View File

@ -39,7 +39,7 @@ function createArrayBufferContainingAllDistinctBytes()
return array.buffer;
}
var ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/websocket_hybi/file_binary-frames");
var ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/websocket_hybi/file_binary-frames");
ws.binaryType = "arraybuffer";
is(ws.binaryType, "arraybuffer", "should be equal to 'arraybuffer'");

View File

@ -39,7 +39,7 @@ function createArrayBufferContainingAllDistinctBytes()
return array.buffer;
}
var ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/websocket_hybi/file_binary-frames");
var ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/websocket_hybi/file_binary-frames");
is(ws.binaryType, "blob", "should be 'blob'");
var closeEvent;

View File

@ -44,7 +44,7 @@ function createArrayBufferContainingAllDistinctBytes()
return array.buffer;
}
var ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/websocket_hybi/file_check-binary-messages");
var ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/websocket_hybi/file_check-binary-messages");
var closeEvent;
ws.onopen = function()

View File

@ -68,7 +68,7 @@ function createBlobContainingAllDistinctBytes()
return createDOMFile("allchars", binaryString);
}
var ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/websocket_hybi/file_check-binary-messages");
var ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/websocket_hybi/file_check-binary-messages");
var closeEvent;
ws.onopen = function()

View File

@ -181,7 +181,6 @@ EXPORTS
sqlite3_vfs_unregister
sqlite3_vfs_register
sqlite3_vmprintf
sqlite3_win32_utf8_to_mbcs
#ifdef SQLITE_DEBUG
sqlite3_mutex_held
sqlite3_mutex_notheld

View File

@ -156,7 +156,7 @@ let DOMApplicationRegistry = {
aCallbak();
});
},
// clones a app object, without the manifest
_cloneAppObject: function(aApp) {
let clone = {
@ -167,14 +167,14 @@ let DOMApplicationRegistry = {
};
return clone;
},
denyInstall: function(aData) {
this.mm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
},
confirmInstall: function(aData) {
confirmInstall: function(aData, aFromSync) {
let app = aData.app;
let id = this._appId(app.origin);
let id = app.syncId || this._appId(app.origin);
// install an application again is considered as an update
if (id) {
@ -199,11 +199,14 @@ let DOMApplicationRegistry = {
delete this.webapps[id].manifest;
this.webapps[id].installTime = (new Date()).getTime()
this._writeFile(this.appsFile, JSON.stringify(this.webapps), (function() {
this.mm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
}).bind(this));
if (!aFromSync)
this._saveApps((function() {
this.mm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
Services.obs.notifyObservers(this, "webapps-sync-install", id);
}).bind(this));
},
_appId: function(aURI) {
for (let id in this.webapps) {
if (this.webapps[id].origin == aURI)
@ -212,6 +215,13 @@ let DOMApplicationRegistry = {
return null;
},
_saveApps: function(aCallback) {
this._writeFile(this.appsFile, JSON.stringify(this.webapps), function() {
if (aCallback)
aCallback();
});
},
/**
* Asynchronously reads a list of manifests
*/
@ -232,23 +242,25 @@ let DOMApplicationRegistry = {
this._readManifests(aData, aFinalCallback, index + 1);
}).bind(this));
},
uninstall: function(aData) {
for (let id in this.webapps) {
let app = this.webapps[id];
if (app.origin == aData.origin) {
delete this.webapps[id];
this._writeFile(this.appsFile, JSON.stringify(this.webapps));
let dir = FileUtils.getDir("ProfD", ["webapps", id], true, true);
try {
dir.remove(true);
} catch (e) {
}
this.mm.sendAsyncMessage("Webapps:Uninstall:Return:OK", aData);
this._saveApps((function() {
this.mm.sendAsyncMessage("Webapps:Uninstall:Return:OK", aData);
Services.obs.notifyObservers(this, "webapps-sync-uninstall", id);
}).bind(this));
}
}
},
enumerate: function(aData) {
aData.apps = [];
let tmp = [];
@ -319,7 +331,6 @@ let DOMApplicationRegistry = {
return;
let id = this._appId(aOrigin);
if (!id) {
aCallback(null);
return;
@ -328,7 +339,76 @@ let DOMApplicationRegistry = {
this._readManifests([{ id: id }], function(aResult) {
aCallback(aResult[0].manifest);
});
}
},
/** added to support the sync engine */
getAppById: function(aId) {
if (!this.webapps[aId])
return null;
let app = this._cloneAppObject(this.webapps[aId]);
return app;
},
itemExists: function(aId) {
return !!this.webapps[aId];
},
updateApps: function(aRecords, aCallback) {
for (let i = 0; i < aRecords.length; i++) {
let record = aRecords[i];
if (record.deleted) {
if (!this.webapps[record.id])
continue;
let origin = this.webapps[record.id].origin;
delete this.webapps[record.id];
let dir = FileUtils.getDir("ProfD", ["webapps", record.id], true, true);
try {
dir.remove(true);
} catch (e) {
}
this.mm.sendAsyncMessage("Webapps:Uninstall:Return:OK", { origin: origin });
} else {
if (!!this.webapps[record.id]) {
this.webapps[record.id] = record.value;
delete this.webapps[record.id].manifest;
}
else {
let data = { app: record.value };
this.confirmInstall(data, true);
this.mm.sendAsyncMessage("Webapps:Install:Return:OK", data);
}
}
}
this._saveApps(aCallback);
},
/*
* May be removed once sync API change
*/
getAllIDs: function() {
let apps = {};
for (let id in this.webapps) {
// only sync http and https apps
if (this.webapps[id].origin.indexOf("http") == 0)
apps[id] = true;
}
return apps;
},
wipe: function(aCallback) {
let ids = this.getAllIDs();
for (let id in ids) {
delete this.webapps[id];
let dir = FileUtils.getDir("ProfD", ["webapps", id], true, true);
try {
dir.remove(true);
} catch (e) {
}
}
this._saveApps(aCallback);
}
};
/**

View File

@ -1503,7 +1503,7 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(DesktopNotificationCenter, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozWebSocket, nsEventTargetSH,
NS_DEFINE_CLASSINFO_DATA(WebSocket, nsEventTargetSH,
EVENTTARGET_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CloseEvent, nsDOMGenericSH,
@ -1569,7 +1569,7 @@ static const nsContractIDMapData kConstructorMap[] =
NS_DEFINE_CONSTRUCTOR_DATA(FormData, NS_FORMDATA_CONTRACTID)
NS_DEFINE_CONSTRUCTOR_DATA(XMLSerializer, NS_XMLSERIALIZER_CONTRACTID)
NS_DEFINE_CONSTRUCTOR_DATA(XMLHttpRequest, NS_XMLHTTPREQUEST_CONTRACTID)
NS_DEFINE_CONSTRUCTOR_DATA(MozWebSocket, NS_WEBSOCKET_CONTRACTID)
NS_DEFINE_CONSTRUCTOR_DATA(WebSocket, NS_WEBSOCKET_CONTRACTID)
NS_DEFINE_CONSTRUCTOR_DATA(XPathEvaluator, NS_XPATH_EVALUATOR_CONTRACTID)
NS_DEFINE_CONSTRUCTOR_DATA(XSLTProcessor,
"@mozilla.org/document-transformer;1?type=xslt")
@ -4114,8 +4114,8 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDesktopNotificationCenter)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(MozWebSocket, nsIMozWebSocket)
DOM_CLASSINFO_MAP_ENTRY(nsIMozWebSocket)
DOM_CLASSINFO_MAP_BEGIN(WebSocket, nsIWebSocket)
DOM_CLASSINFO_MAP_ENTRY(nsIWebSocket)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
DOM_CLASSINFO_MAP_END
@ -6274,7 +6274,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
}
// For now don't expose web sockets unless user has explicitly enabled them
if (name_struct->mDOMClassInfoID == eDOMClassInfo_MozWebSocket_id) {
if (name_struct->mDOMClassInfoID == eDOMClassInfo_WebSocket_id) {
if (!nsWebSocket::PrefEnabled()) {
return NS_OK;
}

View File

@ -500,7 +500,7 @@ DOMCI_CLASS(DesktopNotification)
DOMCI_CLASS(DesktopNotificationCenter)
// WebSocket
DOMCI_CLASS(MozWebSocket)
DOMCI_CLASS(WebSocket)
DOMCI_CLASS(CloseEvent)
DOMCI_CLASS(IDBFactory)

View File

@ -1954,19 +1954,27 @@ nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName,
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<indexedDB::IndexedDatabaseManager> mgr =
indexedDB::IndexedDatabaseManager::GetOrCreate();
NS_ENSURE_TRUE(mgr, NS_ERROR_FAILURE);
indexedDB::IndexedDatabaseManager::Get();
nsRefPtr<indexedDB::FileManager> fileManager =
mgr->GetOrCreateFileManager(origin, aDatabaseName);
NS_ENSURE_TRUE(fileManager, NS_ERROR_FAILURE);
if (mgr) {
nsRefPtr<indexedDB::FileManager> fileManager =
mgr->GetFileManager(origin, aDatabaseName);
nsRefPtr<indexedDB::FileInfo> fileInfo = fileManager->GetFileInfo(aId);
if (fileInfo) {
fileInfo->GetReferences(aRefCnt, aDBRefCnt, aSliceRefCnt);
*aRefCnt--;
*aResult = true;
return NS_OK;
if (fileManager) {
nsRefPtr<indexedDB::FileInfo> fileInfo = fileManager->GetFileInfo(aId);
if (fileInfo) {
fileInfo->GetReferences(aRefCnt, aDBRefCnt, aSliceRefCnt);
if (*aRefCnt != -1) {
// We added an extra temp ref, so account for that accordingly.
(*aRefCnt)--;
}
*aResult = true;
return NS_OK;
}
}
}
*aRefCnt = *aDBRefCnt = *aSliceRefCnt = -1;

View File

@ -117,6 +117,7 @@ IndexInfo::IndexInfo(const IndexInfo& aOther)
: id(aOther.id),
name(aOther.name),
keyPath(aOther.keyPath),
keyPathArray(aOther.keyPathArray),
unique(aOther.unique),
multiEntry(aOther.multiEntry)
{

View File

@ -121,6 +121,7 @@ struct IndexInfo
PRInt64 id;
nsString name;
nsString keyPath;
nsTArray<nsString> keyPathArray;
bool unique;
bool multiEntry;
};
@ -148,6 +149,7 @@ public:
nsString name;
PRInt64 id;
nsString keyPath;
nsTArray<nsString> keyPathArray;
// Main-thread only members. This must *not* be touced on the database thread
nsTArray<IndexInfo> indexes;

View File

@ -131,7 +131,7 @@ private:
class FileInfo##_bits : public FileInfo \
{ \
public: \
FileInfo##_bits(FileManager* aFileManager, PRInt64 aId) \
FileInfo##_bits(FileManager* aFileManager, PRInt##_bits aId) \
: FileInfo(aFileManager), mId(aId) \
{ } \
\

View File

@ -71,21 +71,13 @@ EnumerateToTArray(const PRUint64& aKey,
} // anonymous namespace
nsresult
FileManager::Init()
FileManager::Init(nsIFile* aDirectory,
mozIStorageConnection* aConnection)
{
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
NS_ENSURE_TRUE(mFileInfos.Init(), NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
nsresult
FileManager::InitDirectory(nsIFile* aDirectory,
mozIStorageConnection* aConnection)
{
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
bool exists;
nsresult rv = aDirectory->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
@ -142,7 +134,8 @@ FileManager::InitDirectory(nsIFile* aDirectory,
if (flag) {
rv = ss->UpdateQuotaInformationForFile(file);
NS_ENSURE_SUCCESS(rv, rv);
} else {
}
else {
rv = file->Remove(false);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to remove orphaned file!");
@ -158,9 +151,6 @@ FileManager::InitDirectory(nsIFile* aDirectory,
rv = aDirectory->GetPath(mDirectoryPath);
NS_ENSURE_SUCCESS(rv, rv);
rv = aDirectory->GetLeafName(mDirectoryName);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}

View File

@ -77,12 +77,7 @@ public:
return mDatabaseName;
}
const nsAString& DirectoryName() const
{
return mDirectoryName;
}
bool IsDirectoryInited() const
bool Inited() const
{
return !mDirectoryPath.IsEmpty();
}
@ -97,10 +92,8 @@ public:
return mInvalidated;
}
nsresult Init();
nsresult InitDirectory(nsIFile* aDirectory,
mozIStorageConnection* aConnection);
nsresult Init(nsIFile* aDirectory,
mozIStorageConnection* aConnection);
nsresult Load(mozIStorageConnection* aConnection);
@ -120,7 +113,6 @@ private:
nsString mDatabaseName;
nsString mDirectoryPath;
nsString mDirectoryName;
PRInt64 mLastFileId;

View File

@ -388,6 +388,7 @@ IDBDatabase::CreateObjectStore(const nsAString& aName,
nsString keyPath;
keyPath.SetIsVoid(true);
nsTArray<nsString> keyPathArray;
bool autoIncrement = false;
if (!JSVAL_IS_VOID(aOptions) && !JSVAL_IS_NULL(aOptions)) {
@ -399,6 +400,7 @@ IDBDatabase::CreateObjectStore(const nsAString& aName,
NS_ASSERTION(JSVAL_IS_OBJECT(aOptions), "Huh?!");
JSObject* options = JSVAL_TO_OBJECT(aOptions);
// Get keyPath
jsval val;
if (!JS_GetPropertyById(aCx, options, nsDOMClassInfo::sKeyPath_id, &val)) {
NS_WARNING("JS_GetPropertyById failed!");
@ -406,17 +408,55 @@ IDBDatabase::CreateObjectStore(const nsAString& aName,
}
if (!JSVAL_IS_VOID(val) && !JSVAL_IS_NULL(val)) {
JSString* str = JS_ValueToString(aCx, val);
if (!str) {
NS_WARNING("JS_ValueToString failed!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
if (!JSVAL_IS_PRIMITIVE(val) &&
JS_IsArrayObject(aCx, JSVAL_TO_OBJECT(val))) {
JSObject* obj = JSVAL_TO_OBJECT(val);
jsuint length;
if (!JS_GetArrayLength(aCx, obj, &length)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
if (!length) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
keyPathArray.SetCapacity(length);
for (jsuint index = 0; index < length; index++) {
jsval val;
JSString* jsstr;
nsDependentJSString str;
if (!JS_GetElement(aCx, obj, index, &val) ||
!(jsstr = JS_ValueToString(aCx, val)) ||
!str.init(aCx, jsstr)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
if (!IDBObjectStore::IsValidKeyPath(aCx, str)) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
keyPathArray.AppendElement(str);
}
NS_ASSERTION(!keyPathArray.IsEmpty(), "This shouldn't have happened!");
}
nsDependentJSString dependentKeyPath;
if (!dependentKeyPath.init(aCx, str)) {
NS_WARNING("Initializing keyPath failed!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
else {
JSString* jsstr;
nsDependentJSString str;
if (!(jsstr = JS_ValueToString(aCx, val)) ||
!str.init(aCx, jsstr)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
if (!IDBObjectStore::IsValidKeyPath(aCx, str)) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
keyPath = str;
}
keyPath = dependentKeyPath;
}
if (!JS_GetPropertyById(aCx, options, nsDOMClassInfo::sAutoIncrement_id,
@ -437,13 +477,9 @@ IDBDatabase::CreateObjectStore(const nsAString& aName,
return NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR;
}
if (!keyPath.IsVoid()) {
if (keyPath.IsEmpty() && autoIncrement) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
if (!IDBObjectStore::IsValidKeyPath(aCx, keyPath)) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
if (autoIncrement &&
((!keyPath.IsVoid() && keyPath.IsEmpty()) || !keyPathArray.IsEmpty())) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
nsRefPtr<ObjectStoreInfo> newInfo(new ObjectStoreInfo());
@ -451,6 +487,7 @@ IDBDatabase::CreateObjectStore(const nsAString& aName,
newInfo->name = aName;
newInfo->id = databaseInfo->nextObjectStoreId++;
newInfo->keyPath = keyPath;
newInfo->keyPathArray = keyPathArray;
newInfo->nextAutoIncrementId = autoIncrement ? 1 : 0;
newInfo->comittedAutoIncrementId = newInfo->nextAutoIncrementId;
@ -746,11 +783,30 @@ CreateObjectStoreHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("name"), mObjectStore->Name());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = mObjectStore->HasKeyPath() ?
stmt->BindStringByName(NS_LITERAL_CSTRING("key_path"),
mObjectStore->KeyPath()) :
stmt->BindNullByName(NS_LITERAL_CSTRING("key_path"));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (mObjectStore->UsesKeyPathArray()) {
// We use a comma in the beginning to indicate that it's an array of
// key paths. This is to be able to tell a string-keypath from an
// array-keypath which contains only one item.
// It also makes serializing easier :-)
nsAutoString keyPath;
const nsTArray<nsString>& keyPaths = mObjectStore->KeyPathArray();
for (PRUint32 i = 0; i < keyPaths.Length(); ++i) {
keyPath.Append(NS_LITERAL_STRING(",") + keyPaths[i]);
}
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("key_path"),
keyPath);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
else if (mObjectStore->HasKeyPath()) {
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("key_path"),
mObjectStore->KeyPath());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
else {
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("key_path"));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
rv = stmt->Execute();
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);

View File

@ -49,6 +49,7 @@
#include "nsAppDirectoryServiceDefs.h"
#include "nsComponentManagerUtils.h"
#include "nsIScriptSecurityManager.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsContentUtils.h"
#include "nsDirectoryServiceUtils.h"
#include "nsDOMClassInfoID.h"
@ -202,6 +203,13 @@ IDBFactory::GetDirectoryForOrigin(const nsACString& aASCIIOrigin,
return NS_OK;
}
inline
bool
IgnoreWhitespace(PRUnichar c)
{
return false;
}
// static
nsresult
IDBFactory::LoadDatabaseInformation(mozIStorageConnection* aConnection,
@ -245,8 +253,27 @@ IDBFactory::LoadDatabaseInformation(mozIStorageConnection* aConnection,
else {
NS_ASSERTION(columnType == mozIStorageStatement::VALUE_TYPE_TEXT,
"Should be a string");
rv = stmt->GetString(2, info->keyPath);
nsString keyPath;
rv = stmt->GetString(2, keyPath);
NS_ENSURE_SUCCESS(rv, rv);
if (!keyPath.IsEmpty() && keyPath.First() == ',') {
// We use a comma in the beginning to indicate that it's an array of
// key paths. This is to be able to tell a string-keypath from an
// array-keypath which contains only one item.
nsCharSeparatedTokenizerTemplate<IgnoreWhitespace>
tokenizer(keyPath, ',');
tokenizer.nextToken();
while (tokenizer.hasMoreTokens()) {
info->keyPathArray.AppendElement(tokenizer.nextToken());
}
NS_ASSERTION(!info->keyPathArray.IsEmpty(),
"Should have at least one keypath");
}
else {
info->keyPath = keyPath;
}
}
info->nextAutoIncrementId = stmt->AsInt64(3);
@ -291,8 +318,25 @@ IDBFactory::LoadDatabaseInformation(mozIStorageConnection* aConnection,
rv = stmt->GetString(2, indexInfo->name);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->GetString(3, indexInfo->keyPath);
nsString keyPath;
rv = stmt->GetString(3, keyPath);
NS_ENSURE_SUCCESS(rv, rv);
if (!keyPath.IsEmpty() && keyPath.First() == ',') {
// We use a comma in the beginning to indicate that it's an array of
// key paths. This is to be able to tell a string-keypath from an
// array-keypath which contains only one item.
nsCharSeparatedTokenizerTemplate<IgnoreWhitespace>
tokenizer(keyPath, ',');
tokenizer.nextToken();
while (tokenizer.hasMoreTokens()) {
indexInfo->keyPathArray.AppendElement(tokenizer.nextToken());
}
NS_ASSERTION(!indexInfo->keyPathArray.IsEmpty(),
"Should have at least one keypath");
}
else {
indexInfo->keyPath = keyPath;
}
indexInfo->unique = !!stmt->AsInt32(4);
indexInfo->multiEntry = !!stmt->AsInt32(5);
@ -457,6 +501,6 @@ IDBFactory::Cmp(const jsval& aFirst,
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
*_retval = first == second ? 0 : first < second ? -1 : 1;
*_retval = Key::CompareKeys(first, second);
return NS_OK;
}

View File

@ -48,6 +48,8 @@
#include "nsEventDispatcher.h"
#include "nsThreadUtils.h"
#include "mozilla/storage.h"
#include "xpcprivate.h"
#include "XPCQuickStubs.h"
#include "AsyncConnectionHelper.h"
#include "IDBCursor.h"
@ -319,6 +321,7 @@ IDBIndex::Create(IDBObjectStore* aObjectStore,
index->mId = aIndexInfo->id;
index->mName = aIndexInfo->name;
index->mKeyPath = aIndexInfo->keyPath;
index->mKeyPathArray = aIndexInfo->keyPathArray;
index->mUnique = aIndexInfo->unique;
index->mMultiEntry = aIndexInfo->multiEntry;
@ -380,11 +383,38 @@ IDBIndex::GetStoreName(nsAString& aStoreName)
}
NS_IMETHODIMP
IDBIndex::GetKeyPath(nsAString& aKeyPath)
IDBIndex::GetKeyPath(JSContext* aCx,
jsval* aVal)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
aKeyPath.Assign(mKeyPath);
if (UsesKeyPathArray()) {
JSObject* array = JS_NewArrayObject(aCx, mKeyPathArray.Length(), nsnull);
if (!array) {
NS_WARNING("Failed to make array!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
for (PRUint32 i = 0; i < mKeyPathArray.Length(); ++i) {
jsval val;
nsString tmp(mKeyPathArray[i]);
if (!xpc_qsStringToJsval(aCx, tmp, &val)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
if (!JS_SetElement(aCx, array, i, &val)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
*aVal = OBJECT_TO_JSVAL(array);
}
else {
nsString tmp(mKeyPath);
if (!xpc_qsStringToJsval(aCx, tmp, aVal)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
return NS_OK;
}

View File

@ -97,6 +97,16 @@ public:
return mKeyPath;
}
bool UsesKeyPathArray() const
{
return !mKeyPathArray.IsEmpty();
}
const nsTArray<nsString>& KeyPathArray() const
{
return mKeyPathArray;
}
private:
IDBIndex();
~IDBIndex();
@ -109,6 +119,7 @@ private:
PRInt64 mId;
nsString mName;
nsString mKeyPath;
nsTArray<nsString> mKeyPathArray;
bool mUnique;
bool mMultiEntry;
};

View File

@ -272,7 +272,9 @@ IDBKeyRange::FromJSVal(JSContext* aCx,
if (JSVAL_IS_VOID(aVal) || JSVAL_IS_NULL(aVal)) {
// undefined and null returns no IDBKeyRange.
}
else if (JSVAL_IS_PRIMITIVE(aVal)) {
else if (JSVAL_IS_PRIMITIVE(aVal) ||
JS_IsArrayObject(aCx, JSVAL_TO_OBJECT(aVal)) ||
JS_ObjectIsDate(aCx, JSVAL_TO_OBJECT(aVal))) {
// A valid key returns an 'only' IDBKeyRange.
keyRange = new IDBKeyRange(false, false, true);

View File

@ -55,6 +55,8 @@
#include "nsThreadUtils.h"
#include "snappy/snappy.h"
#include "test_quota.h"
#include "xpcprivate.h"
#include "XPCQuickStubs.h"
#include "AsyncConnectionHelper.h"
#include "IDBCursor.h"
@ -473,6 +475,32 @@ GetKeyFromValue(JSContext* aCx,
return NS_OK;
}
inline
nsresult
GetKeyFromValue(JSContext* aCx,
jsval aVal,
const nsTArray<nsString>& aKeyPathArray,
Key& aKey)
{
NS_ASSERTION(!aKeyPathArray.IsEmpty(),
"Should not use empty keyPath array");
for (PRUint32 i = 0; i < aKeyPathArray.Length(); ++i) {
jsval key;
nsresult rv = GetJSValFromKeyPath(aCx, aVal, aKeyPathArray[i], key);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(aKey.AppendArrayItem(aCx, i == 0, key))) {
NS_ASSERTION(aKey.IsUnset(), "Encoding error should unset");
return NS_OK;
}
}
aKey.FinishArray();
return NS_OK;
}
inline
already_AddRefed<IDBRequest>
GenerateRequest(IDBObjectStore* aObjectStore)
@ -511,6 +539,7 @@ IDBObjectStore::Create(IDBTransaction* aTransaction,
objectStore->mName = aStoreInfo->name;
objectStore->mId = aStoreInfo->id;
objectStore->mKeyPath = aStoreInfo->keyPath;
objectStore->mKeyPathArray = aStoreInfo->keyPathArray;
objectStore->mAutoIncrement = !!aStoreInfo->nextAutoIncrementId;
objectStore->mDatabaseId = aDatabaseId;
objectStore->mInfo = aStoreInfo;
@ -562,14 +591,31 @@ IDBObjectStore::IsValidKeyPath(JSContext* aCx,
nsresult
IDBObjectStore::AppendIndexUpdateInfo(PRInt64 aIndexID,
const nsAString& aKeyPath,
const nsTArray<nsString>& aKeyPathArray,
bool aUnique,
bool aMultiEntry,
JSContext* aCx,
jsval aObject,
jsval aVal,
nsTArray<IndexUpdateInfo>& aUpdateInfoArray)
{
nsresult rv;
if (!aKeyPathArray.IsEmpty()) {
Key arrayKey;
rv = GetKeyFromValue(aCx, aVal, aKeyPathArray, arrayKey);
NS_ENSURE_SUCCESS(rv, rv);
if (!arrayKey.IsUnset()) {
IndexUpdateInfo* updateInfo = aUpdateInfoArray.AppendElement();
updateInfo->indexId = aIndexID;
updateInfo->indexUnique = aUnique;
updateInfo->value = arrayKey;
}
return NS_OK;
}
jsval key;
nsresult rv = GetJSValFromKeyPath(aCx, aObject, aKeyPath, key);
rv = GetJSValFromKeyPath(aCx, aVal, aKeyPath, key);
NS_ENSURE_SUCCESS(rv, rv);
if (aMultiEntry && !JSVAL_IS_PRIMITIVE(key) &&
@ -1126,7 +1172,12 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
else if (!mAutoIncrement) {
// Inline keys live on the object. Make sure that the value passed in is an
// object.
rv = GetKeyFromValue(aCx, aValue, mKeyPath, aKey);
if (UsesKeyPathArray()) {
rv = GetKeyFromValue(aCx, aValue, mKeyPathArray, aKey);
}
else {
rv = GetKeyFromValue(aCx, aValue, mKeyPath, aKey);
}
NS_ENSURE_SUCCESS(rv, rv);
}
@ -1143,8 +1194,9 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
const IndexInfo& indexInfo = mInfo->indexes[indexesIndex];
rv = AppendIndexUpdateInfo(indexInfo.id, indexInfo.keyPath,
indexInfo.unique, indexInfo.multiEntry,
aCx, aValue, aUpdateInfoArray);
indexInfo.keyPathArray, indexInfo.unique,
indexInfo.multiEntry, aCx, aValue,
aUpdateInfoArray);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -1362,11 +1414,38 @@ IDBObjectStore::GetName(nsAString& aName)
}
NS_IMETHODIMP
IDBObjectStore::GetKeyPath(nsAString& aKeyPath)
IDBObjectStore::GetKeyPath(JSContext* aCx,
jsval* aVal)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
aKeyPath.Assign(mKeyPath);
if (UsesKeyPathArray()) {
JSObject* array = JS_NewArrayObject(aCx, mKeyPathArray.Length(), nsnull);
if (!array) {
NS_WARNING("Failed to make array!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
for (PRUint32 i = 0; i < mKeyPathArray.Length(); ++i) {
jsval val;
nsString tmp(mKeyPathArray[i]);
if (!xpc_qsStringToJsval(aCx, tmp, &val)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
if (!JS_SetElement(aCx, array, i, &val)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
*aVal = OBJECT_TO_JSVAL(array);
}
else {
nsString tmp(mKeyPath);
if (!xpc_qsStringToJsval(aCx, tmp, aVal)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
return NS_OK;
}
@ -1611,17 +1690,69 @@ IDBObjectStore::OpenCursor(const jsval& aKey,
NS_IMETHODIMP
IDBObjectStore::CreateIndex(const nsAString& aName,
const nsAString& aKeyPath,
const jsval& aKeyPath,
const jsval& aOptions,
JSContext* aCx,
nsIIDBIndex** _retval)
{
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
if (!IsValidKeyPath(aCx, aKeyPath)) {
return NS_ERROR_DOM_SYNTAX_ERR;
// Get KeyPath
nsString keyPath;
nsTArray<nsString> keyPathArray;
// See if this is a JS array.
if (!JSVAL_IS_PRIMITIVE(aKeyPath) &&
JS_IsArrayObject(aCx, JSVAL_TO_OBJECT(aKeyPath))) {
JSObject* obj = JSVAL_TO_OBJECT(aKeyPath);
jsuint length;
if (!JS_GetArrayLength(aCx, obj, &length)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
if (!length) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
keyPathArray.SetCapacity(length);
for (jsuint index = 0; index < length; index++) {
jsval val;
JSString* jsstr;
nsDependentJSString str;
if (!JS_GetElement(aCx, obj, index, &val) ||
!(jsstr = JS_ValueToString(aCx, val)) ||
!str.init(aCx, jsstr)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
if (!IsValidKeyPath(aCx, str)) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
keyPathArray.AppendElement(str);
}
NS_ASSERTION(!keyPathArray.IsEmpty(), "This shouldn't have happened!");
}
else {
JSString* jsstr;
nsDependentJSString str;
if (!(jsstr = JS_ValueToString(aCx, aKeyPath)) ||
!str.init(aCx, jsstr)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
if (!IsValidKeyPath(aCx, str)) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
keyPath = str;
}
// Check name and current mode
IDBTransaction* transaction = AsyncConnectionHelper::GetCurrentTransaction();
if (!transaction ||
@ -1683,12 +1814,17 @@ IDBObjectStore::CreateIndex(const nsAString& aName,
multiEntry = !!boolVal;
}
if (multiEntry && !keyPathArray.IsEmpty()) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
DatabaseInfo* databaseInfo = mTransaction->DBInfo();
IndexInfo* indexInfo = mInfo->indexes.AppendElement();
indexInfo->id = databaseInfo->nextIndexId++;
indexInfo->name = aName;
indexInfo->keyPath = aKeyPath;
indexInfo->keyPath = keyPath;
indexInfo->keyPathArray.SwapElements(keyPathArray);
indexInfo->unique = unique;
indexInfo->multiEntry = multiEntry;
@ -1908,10 +2044,9 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
mKey.SetFromInteger(autoIncrementNum);
}
else if (mKey.IsInteger() &&
mKey.ToInteger() >= mObjectStore->Info()->nextAutoIncrementId) {
// XXX Once we support floats, we should use floor(mKey.ToFloat()) here
autoIncrementNum = mKey.ToInteger();
else if (mKey.IsFloat() &&
mKey.ToFloat() >= mObjectStore->Info()->nextAutoIncrementId) {
autoIncrementNum = floor(mKey.ToFloat());
}
if (keyUnset && !keyPath.IsEmpty()) {
@ -1925,7 +2060,7 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
PRUint64 u;
} pun;
pun.d = SwapBytes(static_cast<PRUint64>(mKey.ToInteger()));
pun.d = SwapBytes(static_cast<PRUint64>(autoIncrementNum));
JSAutoStructuredCloneBuffer& buffer = mCloneWriteInfo.mCloneBuffer;
PRUint64 offsetToKeyProp = mCloneWriteInfo.mOffsetToKeyProp;
@ -2017,7 +2152,8 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
if (fileIds.IsEmpty()) {
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("file_ids"));
} else {
}
else {
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("file_ids"), fileIds);
}
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -2421,9 +2557,25 @@ CreateIndexHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("name"), mIndex->Name());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("key_path"),
mIndex->KeyPath());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (mIndex->UsesKeyPathArray()) {
// We use a comma in the beginning to indicate that it's an array of
// key paths. This is to be able to tell a string-keypath from an
// array-keypath which contains only one item.
// It also makes serializing easier :-)
nsAutoString keyPath;
const nsTArray<nsString>& keyPaths = mIndex->KeyPathArray();
for (PRUint32 i = 0; i < keyPaths.Length(); ++i) {
keyPath.Append(NS_LITERAL_STRING(",") + keyPaths[i]);
}
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("key_path"),
keyPath);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
else {
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("key_path"),
mIndex->KeyPath());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("unique"),
mIndex->IsUnique() ? 1 : 0);
@ -2519,6 +2671,7 @@ CreateIndexHelper::InsertDataFromObjectStore(mozIStorageConnection* aConnection)
nsTArray<IndexUpdateInfo> updateInfo;
rv = IDBObjectStore::AppendIndexUpdateInfo(mIndex->Id(),
mIndex->KeyPath(),
mIndex->KeyPathArray(),
mIndex->IsUnique(),
mIndex->IsMultiEntry(),
tlsEntry->Context(),

View File

@ -81,6 +81,7 @@ public:
static nsresult
AppendIndexUpdateInfo(PRInt64 aIndexID,
const nsAString& aKeyPath,
const nsTArray<nsString>& aKeyPathArray,
bool aUnique,
bool aMultiEntry,
JSContext* aCx,
@ -159,7 +160,17 @@ public:
const bool HasKeyPath() const
{
return !mKeyPath.IsVoid();
return !mKeyPath.IsVoid() || !mKeyPathArray.IsEmpty();
}
bool UsesKeyPathArray() const
{
return !mKeyPathArray.IsEmpty();
}
const nsTArray<nsString>& KeyPathArray() const
{
return mKeyPathArray;
}
IDBTransaction* Transaction()
@ -199,6 +210,7 @@ private:
PRInt64 mId;
nsString mName;
nsString mKeyPath;
nsTArray<nsString> mKeyPathArray;
bool mAutoIncrement;
nsCOMPtr<nsIAtom> mDatabaseId;
nsRefPtr<ObjectStoreInfo> mInfo;

View File

@ -56,6 +56,7 @@
#include "nsXPCOM.h"
#include "nsXPCOMPrivate.h"
#include "test_quota.h"
#include "xpcprivate.h"
#include "AsyncConnectionHelper.h"
#include "CheckQuotaHelper.h"
@ -683,12 +684,15 @@ IndexedDatabaseManager::EnsureOriginIsInitialized(const nsACString& aOrigin,
// are database files then we need to create file managers for them and also
// tell SQLite about all of them.
nsAutoTArray<nsString, 20> subdirectories;
nsAutoTArray<nsString, 20> subdirsToProcess;
nsAutoTArray<nsCOMPtr<nsIFile> , 20> unknownFiles;
nsAutoPtr<nsTArray<nsRefPtr<FileManager> > > fileManagers(
new nsTArray<nsRefPtr<FileManager> >());
nsTHashtable<nsStringHashKey> validSubdirs;
NS_ENSURE_TRUE(validSubdirs.Init(20), NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsISimpleEnumerator> entries;
rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
NS_ENSURE_SUCCESS(rv, rv);
@ -711,7 +715,9 @@ IndexedDatabaseManager::EnsureOriginIsInitialized(const nsACString& aOrigin,
NS_ENSURE_SUCCESS(rv, rv);
if (isDirectory) {
subdirectories.AppendElement(leafName);
if (!validSubdirs.GetEntry(leafName)) {
subdirsToProcess.AppendElement(leafName);
}
continue;
}
@ -758,30 +764,24 @@ IndexedDatabaseManager::EnsureOriginIsInitialized(const nsACString& aOrigin,
nsRefPtr<FileManager> fileManager = new FileManager(aOrigin, databaseName);
rv = fileManager->Init();
NS_ENSURE_SUCCESS(rv, rv);
rv = fileManager->InitDirectory(fileManagerDirectory, connection);
rv = fileManager->Init(fileManagerDirectory, connection);
NS_ENSURE_SUCCESS(rv, rv);
fileManagers->AppendElement(fileManager);
rv = ss->UpdateQuotaInformationForFile(file);
NS_ENSURE_SUCCESS(rv, rv);
if (!validSubdirs.PutEntry(dbBaseFilename)) {
NS_WARNING("Out of memory?");
return NS_ERROR_OUT_OF_MEMORY;
}
}
NS_ENSURE_SUCCESS(rv, rv);
for (PRUint32 i = 0; i < subdirectories.Length(); i++) {
const nsString& subdirectory = subdirectories[i];
bool unknown = true;
for (PRUint32 j = 0; j < fileManagers->Length(); j++) {
nsRefPtr<FileManager>& fileManager = fileManagers->ElementAt(j);
if (fileManager->DirectoryName().Equals(subdirectory)) {
unknown = false;
break;
}
}
if (unknown) {
for (PRUint32 i = 0; i < subdirsToProcess.Length(); i++) {
const nsString& subdir = subdirsToProcess[i];
if (!validSubdirs.GetEntry(subdir)) {
NS_WARNING("Unknown subdirectory found!");
return NS_ERROR_UNEXPECTED;
}
@ -790,6 +790,8 @@ IndexedDatabaseManager::EnsureOriginIsInitialized(const nsACString& aOrigin,
for (PRUint32 i = 0; i < unknownFiles.Length(); i++) {
nsCOMPtr<nsIFile>& unknownFile = unknownFiles[i];
// Some temporary SQLite files could disappear, so we have to check if the
// unknown file still exists.
bool exists;
rv = unknownFile->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
@ -798,6 +800,7 @@ IndexedDatabaseManager::EnsureOriginIsInitialized(const nsACString& aOrigin,
nsString leafName;
unknownFile->GetLeafName(leafName);
// The journal file may exists even after db has been correctly opened.
if (!StringEndsWith(leafName, NS_LITERAL_STRING(".sqlite-journal"))) {
NS_WARNING("Unknown file found!");
return NS_ERROR_UNEXPECTED;
@ -940,17 +943,33 @@ IndexedDatabaseManager::GetOrCreateFileManager(const nsACString& aOrigin,
if (!fileManager) {
fileManager = new FileManager(aOrigin, aDatabaseName);
if (NS_FAILED(fileManager->Init())) {
NS_WARNING("Failed to initialize file manager!");
return nsnull;
}
array->AppendElement(fileManager);
}
return fileManager.forget();
}
already_AddRefed<FileManager>
IndexedDatabaseManager::GetFileManager(const nsACString& aOrigin,
const nsAString& aDatabaseName)
{
nsTArray<nsRefPtr<FileManager> >* array;
if (!mFileManagers.Get(aOrigin, &array)) {
return nsnull;
}
for (PRUint32 i = 0; i < array->Length(); i++) {
nsRefPtr<FileManager>& fileManager = array->ElementAt(i);
if (fileManager->DatabaseName().Equals(aDatabaseName)) {
nsRefPtr<FileManager> result = fileManager;
return result.forget();
}
}
return nsnull;
}
void
IndexedDatabaseManager::InvalidateFileManagersForOrigin(
const nsACString& aOrigin)
@ -1353,7 +1372,8 @@ IncrementUsage(PRUint64* aUsage, PRUint64 aDelta)
if ((LL_MAXINT - *aUsage) <= aDelta) {
NS_WARNING("Database sizes exceed max we can report!");
*aUsage = LL_MAXINT;
} else {
}
else {
*aUsage += aDelta;
}
}
@ -1438,7 +1458,8 @@ IndexedDatabaseManager::AsyncUsageRunnable::GetUsageForDirectory(
if (isDirectory) {
if (aUsage == &mFileUsage) {
NS_WARNING("Unknown directory found!");
} else {
}
else {
rv = GetUsageForDirectory(file, &mFileUsage);
NS_ENSURE_SUCCESS(rv, rv);
}

View File

@ -181,6 +181,10 @@ public:
GetOrCreateFileManager(const nsACString& aOrigin,
const nsAString& aDatabaseName);
already_AddRefed<FileManager>
GetFileManager(const nsACString& aOrigin,
const nsAString& aDatabaseName);
void InvalidateFileManagersForOrigin(const nsACString& aOrigin);
void InvalidateFileManager(const nsACString& aOrigin,

444
dom/indexedDB/Key.cpp Normal file
View File

@ -0,0 +1,444 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* ***** 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 Indexed Database.
*
* The Initial Developer of the Original Code is The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jan Varga <Jan.Varga@gmail.com>
* Jonas Sicking <jonas@sicking.cc>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "Key.h"
#include "nsIStreamBufferAccess.h"
#include "jsdate.h"
#include "nsContentUtils.h"
#include "nsJSUtils.h"
#include "xpcprivate.h"
#include "XPCQuickStubs.h"
USING_INDEXEDDB_NAMESPACE
/*
Here's how we encode keys:
Basic strategy is the following
Numbers: 1 n n n n n n n n ("n"s are encoded 64bit float)
Dates: 2 n n n n n n n n ("n"s are encoded 64bit float)
Strings: 3 s s s ... 0 ("s"s are encoded unicode bytes)
Arrays: 4 i i i ... 0 ("i"s are encoded array items)
When encoding floats, 64bit IEEE 754 are almost sortable, except that
positive sort lower than negative, and negative sort descending. So we use
the following encoding:
value < 0 ?
(-to64bitInt(value)) :
(to64bitInt(value) | 0x8000000000000000)
When encoding strings, we use variable-size encoding per the following table
Chars 0 - 7E are encoded as 0xxxxxxx with 1 added
Chars 7F - (3FFF+7F) are encoded as 10xxxxxx xxxxxxxx with 7F subtracted
Chars (3FFF+80) - FFFF are encoded as 11xxxxxx xxxxxxxx xx000000
This ensures that the first byte is never encoded as 0, which means that the
string terminator (per basic-stategy table) sorts before any character.
The reason that (3FFF+80) - FFFF is encoded "shifted up" 6 bits is to maximize
the chance that the last character is 0. See below for why.
When encoding Arrays, we use an additional trick. Rather than adding a byte
containing the value '4' to indicate type, we instead add 4 to the next byte.
This is usually the byte containing the type of the first item in the array.
So simple examples are
["foo"] 7 s s s 0 0 // 7 is 3 + 4
[1, 2] 5 n n n n n n n n 1 n n n n n n n n 0 // 5 is 1 + 4
Whe do this iteratively if the first item in the array is also an array
[["foo"]] 11 s s s 0 0 0
However, to avoid overflow in the byte, we only do this 3 times. If the first
item in an array is an array, and that array also has an array as first item,
we simply write out the total value accumulated so far and then follow the
"normal" rules.
[[["foo"]]] 12 3 s s s 0 0 0 0
There is another edge case that can happen though, which is that the array
doesn't have a first item to which we can add 4 to the type. Instead the
next byte would normally be the array terminator (per basic-strategy table)
so we simply add the 4 there.
[[]] 8 0 // 8 is 4 + 4 + 0
[] 4 // 4 is 4 + 0
[[], "foo"] 8 3 s s s 0 0 // 8 is 4 + 4 + 0
Note that the max-3-times rule kicks in before we get a chance to add to the
array terminator
[[[]]] 12 0 0 0 // 12 is 4 + 4 + 4
We could use a much higher number than 3 at no complexity or performance cost,
however it seems unlikely that it'll make a practical difference, and the low
limit makes testing eaiser.
As a final optimization we do a post-encoding step which drops all 0s at the
end of the encoded buffer.
"foo" // 3 s s s
1 // 1 bf f0
["a", "b"] // 7 s 3 s
[1, 2] // 5 bf f0 0 0 0 0 0 0 1 c0
[[]] // 8
*/
const int MaxArrayCollapse = 3;
nsresult
Key::EncodeJSVal(JSContext* aCx, const jsval aVal, PRUint8 aTypeOffset)
{
PR_STATIC_ASSERT(eMaxType * MaxArrayCollapse < 256);
if (JSVAL_IS_STRING(aVal)) {
nsDependentJSString str;
if (!str.init(aCx, aVal)) {
return NS_ERROR_OUT_OF_MEMORY;
}
EncodeString(str, aTypeOffset);
return NS_OK;
}
if (JSVAL_IS_INT(aVal)) {
EncodeNumber((double)JSVAL_TO_INT(aVal), eFloat + aTypeOffset);
return NS_OK;
}
if (JSVAL_IS_DOUBLE(aVal)) {
double d = JSVAL_TO_DOUBLE(aVal);
if (DOUBLE_IS_NaN(d)) {
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
EncodeNumber(d, eFloat + aTypeOffset);
return NS_OK;
}
if (!JSVAL_IS_PRIMITIVE(aVal)) {
JSObject* obj = JSVAL_TO_OBJECT(aVal);
if (JS_IsArrayObject(aCx, obj)) {
aTypeOffset += eMaxType;
if (aTypeOffset == eMaxType * MaxArrayCollapse) {
mBuffer.Append(aTypeOffset);
aTypeOffset = 0;
}
NS_ASSERTION((aTypeOffset % eMaxType) == 0 &&
aTypeOffset < (eMaxType * MaxArrayCollapse),
"Wrong typeoffset");
jsuint length;
if (!JS_GetArrayLength(aCx, obj, &length)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
for (jsuint index = 0; index < length; index++) {
jsval val;
if (!JS_GetElement(aCx, obj, index, &val)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
nsresult rv = EncodeJSVal(aCx, val, aTypeOffset);
NS_ENSURE_SUCCESS(rv, rv);
aTypeOffset = 0;
}
mBuffer.Append(eTerminator + aTypeOffset);
return NS_OK;
}
if (JS_ObjectIsDate(aCx, obj)) {
EncodeNumber(js_DateGetMsecSinceEpoch(aCx, obj), eDate + aTypeOffset);
return NS_OK;
}
}
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
// static
nsresult
Key::DecodeJSVal(const unsigned char*& aPos, const unsigned char* aEnd,
JSContext* aCx, PRUint8 aTypeOffset, jsval* aVal)
{
if (*aPos - aTypeOffset >= eArray) {
JSObject* array = JS_NewArrayObject(aCx, 0, nsnull);
if (!array) {
NS_WARNING("Failed to make array!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
aTypeOffset += eMaxType;
if (aTypeOffset == eMaxType * MaxArrayCollapse) {
++aPos;
aTypeOffset = 0;
}
jsuint index = 0;
while (aPos < aEnd && *aPos - aTypeOffset != eTerminator) {
jsval val;
nsresult rv = DecodeJSVal(aPos, aEnd, aCx, aTypeOffset, &val);
NS_ENSURE_SUCCESS(rv, rv);
aTypeOffset = 0;
if (!JS_SetElement(aCx, array, index++, &val)) {
NS_WARNING("Failed to set array element!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
NS_ASSERTION(aPos >= aEnd || (*aPos % eMaxType) == eTerminator,
"Should have found end-of-array marker");
++aPos;
*aVal = OBJECT_TO_JSVAL(array);
}
else if (*aPos - aTypeOffset == eString) {
nsString key;
DecodeString(aPos, aEnd, key);
if (!xpc_qsStringToJsval(aCx, key, aVal)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
else if (*aPos - aTypeOffset == eDate) {
jsdouble msec = static_cast<jsdouble>(DecodeNumber(aPos, aEnd));
JSObject* date = JS_NewDateObjectMsec(aCx, msec);
if (!date) {
NS_WARNING("Failed to make date!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
*aVal = OBJECT_TO_JSVAL(date);
}
else if (*aPos - aTypeOffset == eFloat) {
*aVal = DOUBLE_TO_JSVAL(DecodeNumber(aPos, aEnd));
}
else {
NS_NOTREACHED("Unknown key type!");
}
return NS_OK;
}
#define ONE_BYTE_LIMIT 0x7E
#define TWO_BYTE_LIMIT (0x3FFF+0x7F)
#define ONE_BYTE_ADJUST 1
#define TWO_BYTE_ADJUST (-0x7F)
#define THREE_BYTE_SHIFT 6
void
Key::EncodeString(const nsAString& aString, PRUint8 aTypeOffset)
{
// First measure how long the encoded string will be.
// The +2 is for initial 3 and trailing 0. We'll compensate for multi-byte
// chars below.
PRUint32 size = aString.Length() + 2;
const PRUnichar* start = aString.BeginReading();
const PRUnichar* end = aString.EndReading();
for (const PRUnichar* iter = start; iter < end; ++iter) {
if (*iter > ONE_BYTE_LIMIT) {
size += *iter > TWO_BYTE_LIMIT ? 2 : 1;
}
}
// Allocate memory for the new size
PRUint32 oldLen = mBuffer.Length();
char* buffer;
if (!mBuffer.GetMutableData(&buffer, oldLen + size)) {
return;
}
buffer += oldLen;
// Write type marker
*(buffer++) = eString + aTypeOffset;
// Encode string
for (const PRUnichar* iter = start; iter < end; ++iter) {
if (*iter <= ONE_BYTE_LIMIT) {
*(buffer++) = *iter + ONE_BYTE_ADJUST;
}
else if (*iter <= TWO_BYTE_LIMIT) {
PRUnichar c = PRUnichar(*iter) + TWO_BYTE_ADJUST + 0x8000;
*(buffer++) = (char)(c >> 8);
*(buffer++) = (char)(c & 0xFF);
}
else {
PRUint32 c = (PRUint32(*iter) << THREE_BYTE_SHIFT) | 0x00C00000;
*(buffer++) = (char)(c >> 16);
*(buffer++) = (char)(c >> 8);
*(buffer++) = (char)c;
}
}
// Write end marker
*(buffer++) = eTerminator;
NS_ASSERTION(buffer == mBuffer.EndReading(), "Wrote wrong number of bytes");
}
// static
void
Key::DecodeString(const unsigned char*& aPos, const unsigned char* aEnd,
nsString& aString)
{
NS_ASSERTION(*aPos % eMaxType == eString, "Don't call me!");
const unsigned char* buffer = aPos + 1;
// First measure how big the decoded string will be.
PRUint32 size = 0;
const unsigned char* iter;
for (iter = buffer; iter < aEnd && *iter != eTerminator; ++iter) {
if (*iter & 0x80) {
iter += (*iter & 0x40) ? 2 : 1;
}
++size;
}
// Set end so that we don't have to check for null termination in the loop
// below
if (iter < aEnd) {
aEnd = iter;
}
PRUnichar* out;
if (size && !aString.GetMutableData(&out, size)) {
return;
}
for (iter = buffer; iter < aEnd;) {
if (!(*iter & 0x80)) {
*out = *(iter++) - ONE_BYTE_ADJUST;
}
else if (!(*iter & 0x40)) {
PRUnichar c = (PRUnichar(*(iter++)) << 8);
if (iter < aEnd) {
c |= *(iter++);
}
*out = c - TWO_BYTE_ADJUST - 0x8000;
}
else {
PRUint32 c = PRUint32(*(iter++)) << (16 - THREE_BYTE_SHIFT);
if (iter < aEnd) {
c |= PRUint32(*(iter++)) << (8 - THREE_BYTE_SHIFT);
}
if (iter < aEnd) {
c |= *(iter++) >> THREE_BYTE_SHIFT;
}
*out = (PRUnichar)c;
}
++out;
}
NS_ASSERTION(!size || out == aString.EndReading(),
"Should have written the whole string");
aPos = iter + 1;
}
union Float64Union {
double d;
PRUint64 u;
};
void
Key::EncodeNumber(double aFloat, PRUint8 aType)
{
// Allocate memory for the new size
PRUint32 oldLen = mBuffer.Length();
char* buffer;
if (!mBuffer.GetMutableData(&buffer, oldLen + 1 + sizeof(double))) {
return;
}
buffer += oldLen;
*(buffer++) = aType;
Float64Union pun;
pun.d = aFloat;
PRUint64 number = pun.u & PR_UINT64(0x8000000000000000) ?
-pun.u :
(pun.u | PR_UINT64(0x8000000000000000));
*reinterpret_cast<PRUint64*>(buffer) = NS_SWAP64(number);
}
// static
double
Key::DecodeNumber(const unsigned char*& aPos, const unsigned char* aEnd)
{
NS_ASSERTION(*aPos % eMaxType == eFloat ||
*aPos % eMaxType == eDate, "Don't call me!");
++aPos;
PRUint64 number = 0;
for (PRInt32 n = 7; n >= 0; --n) {
number <<= 8;
if (aPos < aEnd) {
number |= *(aPos++);
}
else {
number <<= 8 * n;
break;
}
}
Float64Union pun;
pun.u = number & PR_UINT64(0x8000000000000000) ?
(number & ~PR_UINT64(0x8000000000000000)) :
-number;
return pun.d;
}

View File

@ -43,10 +43,6 @@
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
#include "mozIStorageStatement.h"
#include "nsJSUtils.h"
#include "xpcprivate.h"
#include "XPCQuickStubs.h"
BEGIN_INDEXEDDB_NAMESPACE
@ -72,179 +68,161 @@ public:
bool operator==(const Key& aOther) const
{
NS_ASSERTION(mType != KEYTYPE_VOID && aOther.mType != KEYTYPE_VOID,
NS_ASSERTION(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid(),
"Don't compare unset keys!");
if (mType == aOther.mType) {
switch (mType) {
case KEYTYPE_STRING:
return ToString() == aOther.ToString();
case KEYTYPE_INTEGER:
return ToInteger() == aOther.ToInteger();
default:
NS_NOTREACHED("Unknown type!");
}
}
return false;
return mBuffer.Equals(aOther.mBuffer);
}
bool operator!=(const Key& aOther) const
{
return !(*this == aOther);
NS_ASSERTION(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid(),
"Don't compare unset keys!");
return !mBuffer.Equals(aOther.mBuffer);
}
bool operator<(const Key& aOther) const
{
NS_ASSERTION(mType != KEYTYPE_VOID && aOther.mType != KEYTYPE_VOID,
NS_ASSERTION(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid(),
"Don't compare unset keys!");
switch (mType) {
case KEYTYPE_STRING: {
if (aOther.mType == KEYTYPE_INTEGER) {
return false;
}
NS_ASSERTION(aOther.mType == KEYTYPE_STRING, "Unknown type!");
return ToString() < aOther.ToString();
}
case KEYTYPE_INTEGER:
if (aOther.mType == KEYTYPE_STRING) {
return true;
}
NS_ASSERTION(aOther.mType == KEYTYPE_INTEGER, "Unknown type!");
return ToInteger() < aOther.ToInteger();
default:
NS_NOTREACHED("Unknown type!");
}
return false;
return Compare(mBuffer, aOther.mBuffer) < 0;
}
bool operator>(const Key& aOther) const
{
return !(*this == aOther || *this < aOther);
NS_ASSERTION(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid(),
"Don't compare unset keys!");
return Compare(mBuffer, aOther.mBuffer) > 0;
}
bool operator<=(const Key& aOther) const
{
return (*this == aOther || *this < aOther);
NS_ASSERTION(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid(),
"Don't compare unset keys!");
return Compare(mBuffer, aOther.mBuffer) <= 0;
}
bool operator>=(const Key& aOther) const
{
return (*this == aOther || !(*this < aOther));
NS_ASSERTION(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid(),
"Don't compare unset keys!");
return Compare(mBuffer, aOther.mBuffer) >= 0;
}
void
Unset()
{
mType = KEYTYPE_VOID;
mStringKey.SetIsVoid(true);
mIntKey = 0;
mBuffer.SetIsVoid(true);
}
bool IsUnset() const { return mType == KEYTYPE_VOID; }
bool IsString() const { return mType == KEYTYPE_STRING; }
bool IsInteger() const { return mType == KEYTYPE_INTEGER; }
nsresult SetFromString(const nsAString& aString)
bool IsUnset() const
{
mType = KEYTYPE_STRING;
mStringKey = aString;
mIntKey = 0;
return NS_OK;
return mBuffer.IsVoid();
}
nsresult SetFromInteger(PRInt64 aInt)
bool IsFloat() const
{
mType = KEYTYPE_INTEGER;
mStringKey.SetIsVoid(true);
mIntKey = aInt;
return NS_OK;
return !mBuffer.IsVoid() && mBuffer.First() == eFloat;
}
double ToFloat() const
{
NS_ASSERTION(IsFloat(), "Why'd you call this?");
const unsigned char* pos = BufferStart();
double res = DecodeNumber(pos, BufferEnd());
NS_ASSERTION(pos >= BufferEnd(), "Should consume whole buffer");
return res;
}
void SetFromString(const nsAString& aString)
{
mBuffer.Truncate();
EncodeString(aString, 0);
TrimBuffer();
}
void SetFromInteger(PRInt64 aInt)
{
mBuffer.Truncate();
EncodeNumber(double(aInt), eFloat);
TrimBuffer();
}
nsresult SetFromJSVal(JSContext* aCx,
jsval aVal)
const jsval aVal)
{
if (JSVAL_IS_STRING(aVal)) {
nsDependentJSString str;
if (!str.init(aCx, aVal)) {
return NS_ERROR_OUT_OF_MEMORY;
}
return SetFromString(str);
}
if (JSVAL_IS_INT(aVal)) {
SetFromInteger(JSVAL_TO_INT(aVal));
return NS_OK;
}
if (JSVAL_IS_DOUBLE(aVal)) {
jsdouble doubleActual = JSVAL_TO_DOUBLE(aVal);
int64 doubleAsInt = static_cast<int64>(doubleActual);
if (doubleActual == doubleAsInt) {
SetFromInteger(doubleAsInt);
return NS_OK;
}
}
mBuffer.Truncate();
if (JSVAL_IS_NULL(aVal) || JSVAL_IS_VOID(aVal)) {
Unset();
return NS_OK;
}
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
nsresult rv = EncodeJSVal(aCx, aVal, 0);
if (NS_FAILED(rv)) {
Unset();
return rv;
}
TrimBuffer();
return NS_OK;
}
nsresult ToJSVal(JSContext* aCx,
jsval* aVal) const
{
if (IsString()) {
nsString key = ToString();
if (!xpc_qsStringToJsval(aCx, key, aVal)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
else if (IsInteger()) {
if (!JS_NewNumberValue(aCx, static_cast<jsdouble>(ToInteger()), aVal)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
else if (IsUnset()) {
if (IsUnset()) {
*aVal = JSVAL_VOID;
return NS_OK;
}
else {
NS_NOTREACHED("Unknown key type!");
}
const unsigned char* pos = BufferStart();
nsresult rv = DecodeJSVal(pos, BufferEnd(), aCx, 0, aVal);
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(pos >= BufferEnd(),
"Didn't consume whole buffer");
return NS_OK;
}
PRInt64 ToInteger() const
nsresult AppendArrayItem(JSContext* aCx,
bool aFirst,
const jsval aVal)
{
NS_ASSERTION(IsInteger(), "Don't call me!");
return mIntKey;
if (aFirst) {
Unset();
}
nsresult rv = EncodeJSVal(aCx, aVal, aFirst ? eMaxType : 0);
if (NS_FAILED(rv)) {
Unset();
return rv;
}
return NS_OK;
}
const nsString& ToString() const
void FinishArray()
{
NS_ASSERTION(IsString(), "Don't call me!");
return mStringKey;
TrimBuffer();
}
const nsCString& GetBuffer() const
{
return mBuffer;
}
nsresult BindToStatement(mozIStorageStatement* aStatement,
const nsACString& aParamName) const
{
nsresult rv;
if (IsString()) {
rv = aStatement->BindStringByName(aParamName, ToString());
}
else {
NS_ASSERTION(IsInteger(), "Bad key!");
rv = aStatement->BindInt64ByName(aParamName, ToInteger());
}
nsresult rv = aStatement->BindBlobByName(aParamName,
reinterpret_cast<const PRUint8*>(mBuffer.get()), mBuffer.Length());
return NS_SUCCEEDED(rv) ? NS_OK : NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
@ -252,60 +230,83 @@ public:
nsresult SetFromStatement(mozIStorageStatement* aStatement,
PRUint32 aIndex)
{
PRInt32 columnType;
nsresult rv = aStatement->GetTypeOfIndex(aIndex, &columnType);
PRUint8* data;
PRUint32 dataLength = 0;
nsresult rv = aStatement->GetBlob(aIndex, &dataLength, &data);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
NS_ASSERTION(columnType == mozIStorageStatement::VALUE_TYPE_INTEGER ||
columnType == mozIStorageStatement::VALUE_TYPE_TEXT,
"Unsupported column type!");
mBuffer.Adopt(
reinterpret_cast<char*>(const_cast<PRUint8*>(data)), dataLength);
return SetFromStatement(aStatement, aIndex, columnType);
}
nsresult SetFromStatement(mozIStorageStatement* aStatement,
PRUint32 aIndex,
PRInt32 aColumnType)
{
if (aColumnType == mozIStorageStatement::VALUE_TYPE_INTEGER) {
return SetFromInteger(aStatement->AsInt64(aIndex));
}
if (aColumnType == mozIStorageStatement::VALUE_TYPE_TEXT) {
nsString keyString;
nsresult rv = aStatement->GetString(aIndex, keyString);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
return SetFromString(keyString);
}
NS_NOTREACHED("Unsupported column type!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
return NS_OK;
}
static
bool CanBeConstructedFromJSVal(jsval aVal)
PRInt16 CompareKeys(Key& aFirst, Key& aSecond)
{
return JSVAL_IS_INT(aVal) || JSVAL_IS_DOUBLE(aVal) || JSVAL_IS_STRING(aVal);
PRInt32 result = Compare(aFirst.mBuffer, aSecond.mBuffer);
if (result < 0) {
return -1;
}
if (result > 0) {
return 1;
}
return 0;
}
private:
// Wish we could use JSType here but we will end up supporting types like Date
// which JSType can't really identify. Rolling our own for now.
enum Type {
KEYTYPE_VOID,
KEYTYPE_STRING,
KEYTYPE_INTEGER
const unsigned char* BufferStart() const
{
return reinterpret_cast<const unsigned char*>(mBuffer.BeginReading());
}
const unsigned char* BufferEnd() const
{
return reinterpret_cast<const unsigned char*>(mBuffer.EndReading());
}
enum {
eTerminator = 0,
eFloat = 1,
eDate = 2,
eString = 3,
eArray = 4,
eMaxType = eArray
};
// Type of value in mJSVal.
Type mType;
// Encoding helper. Trims trailing zeros off of mBuffer as a post-processing
// step.
void TrimBuffer()
{
const char* end = mBuffer.EndReading() - 1;
while (!*end) {
--end;
}
// The string if mType is KEYTYPE_STRING, otherwise a void string.
nsString mStringKey;
mBuffer.Truncate(end + 1 - mBuffer.BeginReading());
}
// The integer value if mType is KEYTYPE_INTEGER, otherwise 0.
int64 mIntKey;
// Encoding functions. These append the encoded value to the end of mBuffer
nsresult EncodeJSVal(JSContext* aCx, const jsval aVal, PRUint8 aTypeOffset);
void EncodeString(const nsAString& aString, PRUint8 aTypeOffset);
void EncodeNumber(double aFloat, PRUint8 aType);
// Decoding functions. aPos points into mBuffer and is adjusted to point
// past the consumed value.
static nsresult DecodeJSVal(const unsigned char*& aPos,
const unsigned char* aEnd, JSContext* aCx,
PRUint8 aTypeOffset, jsval* aVal);
static void DecodeString(const unsigned char*& aPos,
const unsigned char* aEnd,
nsString& aString);
static double DecodeNumber(const unsigned char*& aPos,
const unsigned char* aEnd);
nsCString mBuffer;
};
END_INDEXEDDB_NAMESPACE

View File

@ -71,6 +71,7 @@ CPPSRCS = \
LazyIdleThread.cpp \
OpenDatabaseHelper.cpp \
TransactionThreadPool.cpp \
Key.cpp \
$(NULL)
EXPORTS_mozilla/dom/indexedDB = \

View File

@ -60,7 +60,7 @@ namespace {
PR_STATIC_ASSERT(JS_STRUCTURED_CLONE_VERSION == 1);
// Major schema version. Bump for almost everything.
const PRUint32 kMajorSchemaVersion = 11;
const PRUint32 kMajorSchemaVersion = 12;
// Minor schema version. Should almost always be 0 (maybe bump on release
// branches if we have to).
@ -215,9 +215,9 @@ CreateTables(mozIStorageConnection* aDBConn)
"CREATE TABLE object_data ("
"id INTEGER PRIMARY KEY, "
"object_store_id INTEGER NOT NULL, "
"key_value DEFAULT NULL, "
"data BLOB NOT NULL, "
"key_value BLOB DEFAULT NULL, "
"file_ids TEXT, "
"data BLOB NOT NULL, "
"UNIQUE (object_store_id, key_value), "
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
"CASCADE"
@ -245,8 +245,8 @@ CreateTables(mozIStorageConnection* aDBConn)
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TABLE index_data ("
"index_id INTEGER NOT NULL, "
"value NOT NULL, "
"object_data_key NOT NULL, "
"value BLOB NOT NULL, "
"object_data_key BLOB NOT NULL, "
"object_data_id INTEGER NOT NULL, "
"PRIMARY KEY (index_id, value, object_data_key), "
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
@ -268,8 +268,8 @@ CreateTables(mozIStorageConnection* aDBConn)
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TABLE unique_index_data ("
"index_id INTEGER NOT NULL, "
"value NOT NULL, "
"object_data_key NOT NULL, " // NONE affinity
"value BLOB NOT NULL, "
"object_data_key BLOB NOT NULL, "
"object_data_id INTEGER NOT NULL, "
"PRIMARY KEY (index_id, value, object_data_key), "
"UNIQUE (index_id, value), "
@ -1019,6 +1019,11 @@ UpgradeSchemaFrom10_0To11_0(mozIStorageConnection* aConnection)
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"DROP TRIGGER object_data_insert_trigger;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"INSERT INTO object_data (object_store_id, key_value, data, file_ids) "
"SELECT object_store_id, id, data, file_ids "
@ -1026,6 +1031,17 @@ UpgradeSchemaFrom10_0To11_0(mozIStorageConnection* aConnection)
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TRIGGER object_data_insert_trigger "
"AFTER INSERT ON object_data "
"FOR EACH ROW "
"WHEN NEW.file_ids IS NOT NULL "
"BEGIN "
"SELECT update_refcount(NULL, NEW.file_ids); "
"END;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"INSERT INTO index_data (index_id, value, object_data_key, object_data_id) "
"SELECT ai_index_data.index_id, ai_index_data.value, ai_index_data.ai_object_data_id, object_data.id "
@ -1078,6 +1094,269 @@ UpgradeSchemaFrom10_0To11_0(mozIStorageConnection* aConnection)
return NS_OK;
}
class EncodeKeysFunction : public mozIStorageFunction
{
public:
NS_DECL_ISUPPORTS
NS_IMETHOD
OnFunctionCall(mozIStorageValueArray* aArguments,
nsIVariant** aResult)
{
PRUint32 argc;
nsresult rv = aArguments->GetNumEntries(&argc);
NS_ENSURE_SUCCESS(rv, rv);
if (argc != 1) {
NS_WARNING("Don't call me with the wrong number of arguments!");
return NS_ERROR_UNEXPECTED;
}
PRInt32 type;
rv = aArguments->GetTypeOfIndex(0, &type);
NS_ENSURE_SUCCESS(rv, rv);
Key key;
if (type == mozIStorageStatement::VALUE_TYPE_INTEGER) {
PRInt64 intKey;
aArguments->GetInt64(0, &intKey);
key.SetFromInteger(intKey);
}
else if (type == mozIStorageStatement::VALUE_TYPE_TEXT) {
nsString stringKey;
aArguments->GetString(0, stringKey);
key.SetFromString(stringKey);
}
else {
NS_WARNING("Don't call me with the wrong type of arguments!");
return NS_ERROR_UNEXPECTED;
}
const nsCString& buffer = key.GetBuffer();
std::pair<const void *, int> data(static_cast<const void*>(buffer.get()),
int(buffer.Length()));
nsCOMPtr<nsIVariant> result = new mozilla::storage::BlobVariant(data);
result.forget(aResult);
return NS_OK;
}
};
NS_IMPL_ISUPPORTS1(EncodeKeysFunction, mozIStorageFunction)
nsresult
UpgradeSchemaFrom11_0To12_0(mozIStorageConnection* aConnection)
{
NS_NAMED_LITERAL_CSTRING(encoderName, "encode");
nsCOMPtr<mozIStorageFunction> encoder = new EncodeKeysFunction();
nsresult rv = aConnection->CreateFunction(encoderName, 1, encoder);
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TEMPORARY TABLE temp_upgrade ("
"id INTEGER PRIMARY KEY, "
"object_store_id, "
"key_value, "
"data, "
"file_ids "
");"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"INSERT INTO temp_upgrade "
"SELECT id, object_store_id, encode(key_value), data, file_ids "
"FROM object_data;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"DROP TABLE object_data;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TABLE object_data ("
"id INTEGER PRIMARY KEY, "
"object_store_id INTEGER NOT NULL, "
"key_value BLOB DEFAULT NULL, "
"file_ids TEXT, "
"data BLOB NOT NULL, "
"UNIQUE (object_store_id, key_value), "
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
"CASCADE"
");"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"INSERT INTO object_data "
"SELECT id, object_store_id, key_value, file_ids, data "
"FROM temp_upgrade;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"DROP TABLE temp_upgrade;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TRIGGER object_data_insert_trigger "
"AFTER INSERT ON object_data "
"FOR EACH ROW "
"WHEN NEW.file_ids IS NOT NULL "
"BEGIN "
"SELECT update_refcount(NULL, NEW.file_ids); "
"END;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TRIGGER object_data_update_trigger "
"AFTER UPDATE OF file_ids ON object_data "
"FOR EACH ROW "
"WHEN OLD.file_ids IS NOT NULL OR NEW.file_ids IS NOT NULL "
"BEGIN "
"SELECT update_refcount(OLD.file_ids, NEW.file_ids); "
"END;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TRIGGER object_data_delete_trigger "
"AFTER DELETE ON object_data "
"FOR EACH ROW WHEN OLD.file_ids IS NOT NULL "
"BEGIN "
"SELECT update_refcount(OLD.file_ids, NULL); "
"END;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TEMPORARY TABLE temp_upgrade ("
"index_id, "
"value, "
"object_data_key, "
"object_data_id "
");"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"INSERT INTO temp_upgrade "
"SELECT index_id, encode(value), encode(object_data_key), object_data_id "
"FROM index_data;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"DROP TABLE index_data;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TABLE index_data ("
"index_id INTEGER NOT NULL, "
"value BLOB NOT NULL, "
"object_data_key BLOB NOT NULL, "
"object_data_id INTEGER NOT NULL, "
"PRIMARY KEY (index_id, value, object_data_key), "
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
"CASCADE, "
"FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE "
"CASCADE"
");"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"INSERT INTO index_data "
"SELECT index_id, value, object_data_key, object_data_id "
"FROM temp_upgrade;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"DROP TABLE temp_upgrade;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE INDEX index_data_object_data_id_index "
"ON index_data (object_data_id);"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TEMPORARY TABLE temp_upgrade ("
"index_id, "
"value, "
"object_data_key, "
"object_data_id "
");"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"INSERT INTO temp_upgrade "
"SELECT index_id, encode(value), encode(object_data_key), object_data_id "
"FROM unique_index_data;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"DROP TABLE unique_index_data;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TABLE unique_index_data ("
"index_id INTEGER NOT NULL, "
"value BLOB NOT NULL, "
"object_data_key BLOB NOT NULL, "
"object_data_id INTEGER NOT NULL, "
"PRIMARY KEY (index_id, value, object_data_key), "
"UNIQUE (index_id, value), "
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
"CASCADE "
"FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE "
"CASCADE"
");"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"INSERT INTO unique_index_data "
"SELECT index_id, value, object_data_key, object_data_id "
"FROM temp_upgrade;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"DROP TABLE temp_upgrade;"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE INDEX unique_index_data_object_data_id_index "
"ON unique_index_data (object_data_id);"
));
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->RemoveFunction(encoderName);
NS_ENSURE_SUCCESS(rv, rv);
rv = aConnection->SetSchemaVersion(MakeSchemaVersion(12, 0));
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
class VersionChangeEventsRunnable;
class SetVersionHelper : public AsyncConnectionHelper,
@ -1417,8 +1696,8 @@ OpenDatabaseHelper::DoDatabaseWork()
mFileManager = mgr->GetOrCreateFileManager(mASCIIOrigin, mName);
NS_ENSURE_TRUE(mFileManager, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (!mFileManager->IsDirectoryInited()) {
rv = mFileManager->InitDirectory(fileManagerDirectory, connection);
if (!mFileManager->Inited()) {
rv = mFileManager->Init(fileManagerDirectory, connection);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
@ -1529,7 +1808,7 @@ OpenDatabaseHelper::CreateDatabaseConnection(
}
else {
// This logic needs to change next time we change the schema!
PR_STATIC_ASSERT(kSQLiteSchemaVersion == PRInt32((11 << 4) + 0));
PR_STATIC_ASSERT(kSQLiteSchemaVersion == PRInt32((12 << 4) + 0));
while (schemaVersion != kSQLiteSchemaVersion) {
if (schemaVersion == 4) {
@ -1554,6 +1833,9 @@ OpenDatabaseHelper::CreateDatabaseConnection(
else if (schemaVersion == MakeSchemaVersion(10, 0)) {
rv = UpgradeSchemaFrom10_0To11_0(connection);
}
else if (schemaVersion == MakeSchemaVersion(11, 0)) {
rv = UpgradeSchemaFrom11_0To12_0(connection);
}
else {
NS_WARNING("Unable to open IndexedDB database, no upgrade path is "
"available!");

View File

@ -47,14 +47,15 @@ interface nsIIDBRequest;
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBIndex for more
* information.
*/
[scriptable, builtinclass, uuid(fcb9a158-833e-4aa9-ab19-ab90cbb50afc)]
[scriptable, builtinclass, uuid(233ec586-7b34-4263-b27e-a4991b757597)]
interface nsIIDBIndex : nsISupports
{
readonly attribute DOMString name;
readonly attribute DOMString storeName;
readonly attribute DOMString keyPath;
[implicit_jscontext]
readonly attribute jsval keyPath;
readonly attribute boolean unique;

View File

@ -50,12 +50,13 @@ interface nsIDOMDOMStringList;
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-nsIIDBObjectStore
* for more information.
*/
[scriptable, builtinclass, uuid(e93c5ca4-89da-4eb4-b839-271ba4f65a27)]
[scriptable, builtinclass, uuid(e0d308ea-b804-4962-918a-28ec0aa4e42b)]
interface nsIIDBObjectStore : nsISupports
{
readonly attribute DOMString name;
readonly attribute DOMString keyPath;
[implicit_jscontext]
readonly attribute jsval keyPath;
readonly attribute nsIDOMDOMStringList indexNames;
@ -111,7 +112,7 @@ interface nsIIDBObjectStore : nsISupports
[implicit_jscontext]
nsIIDBIndex
createIndex([Null(Stringify)] in DOMString name,
[Null(Stringify)] in DOMString keyPath,
in jsval keyPath,
[optional /* none */] in jsval options);
// Returns object immediately

View File

@ -60,7 +60,6 @@ TEST_FILES = \
test_autoIncrement.html \
test_bfcache.html \
test_clear.html \
test_cmp.html \
test_complex_keyPaths.html \
test_count.html \
test_create_index.html \
@ -79,6 +78,7 @@ TEST_FILES = \
test_file_cross_database_copying.html \
test_file_delete.html \
test_file_os_delete.html \
test_file_put_get_object.html \
test_file_put_get_values.html \
test_file_resurrection_delete.html \
test_file_resurrection_transaction_abort.html \
@ -94,6 +94,7 @@ TEST_FILES = \
test_indexes.html \
test_indexes_bad_values.html \
test_key_requirements.html \
test_keys.html \
test_leaving_page.html \
test_multientry.html \
test_objectCursors.html \

View File

@ -111,7 +111,8 @@ function verifyBlob(blob1, blob2, fileId, blobReadHandler)
verifyBuffers(buffer1, buffer2);
if (blobReadHandler) {
blobReadHandler();
} else {
}
else {
testGenerator.next();
}
}
@ -126,7 +127,8 @@ function verifyBlob(blob1, blob2, fileId, blobReadHandler)
verifyBuffers(buffer1, buffer2);
if (blobReadHandler) {
blobReadHandler();
} else {
}
else {
testGenerator.next();
}
}
@ -147,7 +149,8 @@ function verifyBlobArray(blobs1, blobs2, expectedFileIds)
function blobReadHandler() {
if (++verifiedCount == blobs1.length) {
testGenerator.next();
} else {
}
else {
verifyBlob(blobs1[verifiedCount], blobs2[verifiedCount],
expectedFileIds[verifiedCount], blobReadHandler);
}

View File

@ -85,6 +85,36 @@ ExpectError.prototype = {
}
};
function compareKeys(k1, k2) {
let t = typeof k1;
if (t != typeof k2)
return false;
if (t !== "object")
return k1 === k2;
if (k1 instanceof Date) {
return (k2 instanceof Date) &&
k1.getTime() === k2.getTime();
}
if (k1 instanceof Array) {
if (!(k2 instanceof Array) ||
k1.length != k2.length)
return false;
for (let i = 0; i < k1.length; ++i) {
if (!compareKeys(k1[i], k2[i]))
return false;
}
return true;
}
return false;
}
function addPermission(type, allow, url)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
@ -94,14 +124,16 @@ function addPermission(type, allow, url)
uri = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
} else {
}
else {
uri = SpecialPowers.getDocumentURIObject(window.document);
}
let permission;
if (allow) {
permission = Components.interfaces.nsIPermissionManager.ALLOW_ACTION;
} else {
}
else {
permission = Components.interfaces.nsIPermissionManager.DENY_ACTION;
}

View File

@ -12,7 +12,8 @@
<script type="text/javascript;version=1.7">
function genCheck(key, value, test, options) {
return function(event) {
is(event.target.result, key, "correct returned key in " + test);
is(JSON.stringify(event.target.result), JSON.stringify(key),
"correct returned key in " + test);
if (options && options.store) {
is(event.target.source, options.store, "correct store in " + test);
}
@ -120,6 +121,14 @@
genCheck(c1++, { explicit: 8 }, "eighth" + test);
yield;
trans = db.transaction("store1", RW);
trans.objectStore("store1").add({ explicit: 7 }, [100000]).onsuccess =
genCheck([100000], { explicit: 7 }, "seventh" + test);
yield;
trans.objectStore("store1").add({ explicit: 8 }).onsuccess =
genCheck(c1++, { explicit: 8 }, "eighth" + test);
yield;
trans = db.transaction("store1", RW);
trans.objectStore("store1").add({ explicit: 9 }, -100000).onsuccess =
genCheck(-100000, { explicit: 9 }, "ninth" + test);
@ -166,6 +175,15 @@
c2++;
yield;
trans = db.transaction("store2", RW);
trans.objectStore("store2").add({ explicit: 7, id: [100000] }).onsuccess =
genCheck([100000], { explicit: 7, id: [100000] }, "seventh store2" + test);
yield;
trans.objectStore("store2").add({ explicit: 8 }).onsuccess =
genCheck(c2, { explicit: 8, id: c2 }, "eighth store2" + test);
c2++;
yield;
trans = db.transaction("store2", RW);
trans.objectStore("store2").add({ explicit: 9, id: -100000 }).onsuccess =
genCheck(-100000, { explicit: 9, id: -100000 }, "ninth store2" + test);

View File

@ -1,85 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Property Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
function compare(key1, key2, expected, exception) {
function maybeQuote(key) {
return typeof(key) == "string" ? "\"" + key + "\"" : key;
}
var cmp = "cmp(" + maybeQuote(key1) + ", " + maybeQuote(key2) + ")";
if (exception) {
var caught;
try {
var result = mozIndexedDB.cmp(key1, key2);
}
catch(e) {
caught = e;
}
ok(caught, "Got an exception for " + cmp);
is(caught instanceof IDBDatabaseException, true,
"Got IDBDatabaseException for " + cmp);
is(caught.code, IDBDatabaseException.DATA_ERR,
"Got correct exception code for " + cmp);
}
else {
is(mozIndexedDB.cmp(key1, key2), expected,
"Correct result for " + cmp);
}
}
compare(NaN, 0, 0, true);
compare(0, NaN, 0, true);
compare(undefined, 0, 0, true);
compare(0, undefined, 0, true);
compare(null, 0, 0, true);
compare(0, null, 0, true);
compare(0, 0, 0);
compare(1, 0, 1);
compare(0, 1, -1);
compare(1, 1, 0);
compare(2, 1, 1);
compare(1, 2, -1);
compare(-1, -1, 0);
compare(0, -1, 1);
compare(-1, 0, -1);
compare("", "", 0);
compare("a", "", 1);
compare("", "a", -1);
compare("a", "a", 0);
compare("a", "b", -1);
compare("b", "a", 1);
compare("a", "aa", -1);
compare("aa", "a", 1);
compare(0, "", -1);
compare("", 0, 1);
compare(0, "a", -1);
compare("a", 0, 1);
compare(99999, "", -1);
compare("", 99999, 1);
finishTest();
yield;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View File

@ -48,6 +48,26 @@
{ keyPath: "foo.2.bar", exception: true },
{ keyPath: "foo. .bar", exception: true },
{ keyPath: ".bar", exception: true },
{ keyPath: ["foo", "bar"], value: { foo: 1, bar: 2 }, key: [1, 2] },
{ keyPath: ["foo"], value: { foo: 1, bar: 2 }, key: [1] },
{ keyPath: ["foo", "bar", "bar"], value: { foo: 1, bar: "x" }, key: [1, "x", "x"] },
{ keyPath: ["x", "y"], value: { x: [], y: "x" }, key: [[], "x"] },
{ keyPath: ["x", "y"], value: { x: [[1]], y: "x" }, key: [[[1]], "x"] },
{ keyPath: ["x", "y"], value: { x: [[1]], y: new Date(1) }, key: [[[1]], new Date(1)] },
{ keyPath: ["x", "y"], value: { x: [[1]], y: [new Date(3)] }, key: [[[1]], [new Date(3)]] },
{ keyPath: ["x", "y.bar"], value: { x: "hi", y: { bar: "x"} }, key: ["hi", "x"] },
{ keyPath: ["x.y", "y.bar"], value: { x: { y: "hello" }, y: { bar: "nurse"} }, key: ["hello", "nurse"] },
{ keyPath: ["", ""], value: 5, key: [5, 5] },
{ keyPath: ["x", "y"], value: { x: 1 } },
{ keyPath: ["x", "y"], value: { y: 1 } },
{ keyPath: ["x", "y"], value: { x: 1, y: undefined } },
{ keyPath: ["x", "y"], value: { x: null, y: 1 } },
{ keyPath: ["x", "y.bar"], value: { x: null, y: { bar: "x"} } },
{ keyPath: ["x", "y"], value: { x: 1, y: false } },
{ keyPath: ["x", "y", "z"], value: { x: 1, y: false, z: "a" } },
{ keyPath: [".x", "y", "z"], exception: true },
{ keyPath: ["x", "y ", "z"], exception: true },
];
let openRequest = mozIndexedDB.open(name, 1);
@ -62,13 +82,16 @@
// Test creating object stores and inserting data
for (let i = 0; i < keyPaths.length; i++) {
let info = keyPaths[i];
let test = " for objectStore test " + JSON.stringify(info);
if (!stores[info.keyPath]) {
let indexName = JSON.stringify(info.keyPath);
if (!stores[indexName]) {
try {
let objectStore = db.createObjectStore(info.keyPath, { keyPath: info.keyPath });
let objectStore = db.createObjectStore(indexName, { keyPath: info.keyPath });
ok(!("exception" in info), "shouldn't throw" + test);
is(objectStore.keyPath, info.keyPath, "correct keyPath property" + test);
stores[info.keyPath] = objectStore;
is(JSON.stringify(objectStore.keyPath), JSON.stringify(info.keyPath),
"correct keyPath property" + test);
stores[indexName] = objectStore;
} catch (e) {
ok("exception" in info, "should throw" + test);
ok(e instanceof DOMException, "Got a DOM Exception" + test);
@ -77,7 +100,7 @@
}
}
let store = stores[info.keyPath];
let store = stores[indexName];
try {
request = store.add(info.value);
@ -95,7 +118,12 @@
let e = yield;
is(e.type, "success", "inserted successfully" + test);
is(e.target, request, "expected target" + test);
is(request.result, info.key, "found correct key" + test);
ok(compareKeys(request.result, info.key), "found correct key" + test);
is(mozIndexedDB.cmp(request.result, info.key), 0, "returned key compares correctly" + test);
store.get(info.key).onsuccess = grabEventAndContinueHandler;
e = yield;
isnot(e.target.result, undefined, "Did find entry");
store.clear().onsuccess = grabEventAndContinueHandler;
yield;
@ -107,12 +135,14 @@
for (let i = 0; i < keyPaths.length; i++) {
let test = " for index test " + JSON.stringify(info);
let info = keyPaths[i];
if (!indexes[info.keyPath]) {
let indexName = JSON.stringify(info.keyPath);
if (!indexes[indexName]) {
try {
let index = store.createIndex(info.keyPath, info.keyPath);
let index = store.createIndex(indexName, info.keyPath);
ok(!("exception" in info), "shouldn't throw" + test);
is(index.keyPath, info.keyPath, "index has correct keyPath property" + test);
indexes[info.keyPath] = index;
is(JSON.stringify(index.keyPath), JSON.stringify(info.keyPath),
"index has correct keyPath property" + test);
indexes[indexName] = index;
} catch (e) {
ok("exception" in info, "should throw" + test);
ok(e instanceof DOMException, "Got a DOM Exception" + test);
@ -121,7 +151,7 @@
}
}
let index = indexes[info.keyPath];
let index = indexes[indexName];
request = store.add(info.value, 1);
if ("key" in info) {

View File

@ -50,6 +50,22 @@
ok(true, "createIndex with no keyPath should throw");
}
try {
request = objectStore.createIndex("Hola", ["foo"], { multiEntry: true });
ok(false, "createIndex with array keyPath and multiEntry should throw");
}
catch(e) {
ok(true, "createIndex with array keyPath and multiEntry should throw");
}
try {
request = objectStore.createIndex("Hola", []);
ok(false, "createIndex with empty array keyPath should throw");
}
catch(e) {
ok(true, "createIndex with empty array keyPath should throw");
}
try {
request = objectStore.createIndex("foo", "bar", 10);
ok(false, "createIndex with bad options should throw");

View File

@ -52,6 +52,14 @@
ok(true, "createObjectStore with bad options");
}
try {
db.createObjectStore("foo", { keyPath: ["foo"], autoIncrement: true });
ok(false, "createObjectStore with keyPath-array and autoIncrement should throw");
}
catch(e) {
ok(true, "createObjectStore with keyPath-array and autoIncrement should throw");
}
ok(db.createObjectStore("foo", { foo: "" }),
"createObjectStore with unknown options should not throw");
db.deleteObjectStore("foo");

View File

@ -0,0 +1,87 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Property Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const READ_WRITE = IDBTransaction.READ_WRITE;
const name = window.location.pathname;
const description = "My Test Database";
const objectStoreName = "Blobs";
const blob = getRandomBlob(1000);
const file = getRandomFile("random.bin", 100000);
const objectData1 = { key: 1, object: { foo: blob, bar: blob } };
const objectData2 = { key: 2, object: { foo: file, bar: file } };
let request = mozIndexedDB.open(name, 1, description);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
is(event.type, "upgradeneeded", "Got correct event type");
let db = event.target.result;
db.onerror = errorHandler;
let objectStore = db.createObjectStore(objectStoreName, { });
objectStore.add(objectData1.object, objectData1.key);
objectStore.add(objectData2.object, objectData2.key);
event = yield;
is(event.type, "success", "Got correct event type");
objectStore = db.transaction([objectStoreName])
.objectStore(objectStoreName);
request = objectStore.get(objectData1.key);
request.onsuccess = grabEventAndContinueHandler;
event = yield;
let result = event.target.result;
verifyBlob(result.foo, blob, 1);
yield;
verifyBlob(result.bar, blob, 1);
yield;
objectStore = db.transaction([objectStoreName])
.objectStore(objectStoreName);
request = objectStore.get(objectData2.key);
request.onsuccess = grabEventAndContinueHandler;
event = yield;
result = event.target.result;
verifyBlob(result.foo, file, 2);
yield;
verifyBlob(result.bar, file, 2);
yield;
finishTest();
yield;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

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