Merge mozilla-central to mozilla-inbound
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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"/>
|
||||
|
@ -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]));
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -729,7 +729,9 @@ var PlacesUIUtils = {
|
||||
}
|
||||
}
|
||||
}
|
||||
aWindow.openUILinkIn(aNode.uri, aWhere);
|
||||
aWindow.openUILinkIn(aNode.uri, aWhere, {
|
||||
inBackground: Services.prefs.getBoolPref("browser.tabs.loadBookmarksInBackground")
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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 || "");
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 -->
|
||||
|
@ -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++;
|
||||
|
@ -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();
|
||||
|
@ -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:">
|
||||
|
@ -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:">
|
||||
|
@ -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 {
|
||||
|
112
browser/themes/gnomestripe/devtools/common.css
Normal 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%);
|
||||
}
|
Before Width: | Height: | Size: 784 B |
BIN
browser/themes/gnomestripe/devtools/itemArrow-ltr.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
browser/themes/gnomestripe/devtools/itemArrow-rtl.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
browser/themes/gnomestripe/devtools/itemToggle.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
browser/themes/gnomestripe/devtools/magnifying-glass.png
Normal file
After Width: | Height: | Size: 275 B |
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
113
browser/themes/pinstripe/devtools/common.css
Normal 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%);
|
||||
}
|
Before Width: | Height: | Size: 784 B |
BIN
browser/themes/pinstripe/devtools/itemArrow-ltr.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
browser/themes/pinstripe/devtools/itemArrow-rtl.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
browser/themes/pinstripe/devtools/itemToggle.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
browser/themes/pinstripe/devtools/magnifying-glass.png
Normal file
After Width: | Height: | Size: 275 B |
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
120
browser/themes/winstripe/devtools/common.css
Normal 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%);
|
||||
}
|
Before Width: | Height: | Size: 784 B |
BIN
browser/themes/winstripe/devtools/itemArrow-ltr.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
browser/themes/winstripe/devtools/itemArrow-rtl.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
browser/themes/winstripe/devtools/itemToggle.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
browser/themes/winstripe/devtools/magnifying-glass.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -117,7 +117,7 @@ XPIDLSRCS = \
|
||||
nsIXMLHttpRequest.idl \
|
||||
nsIContentSecurityPolicy.idl \
|
||||
nsIFrameMessageManager.idl \
|
||||
nsIMozWebSocket.idl \
|
||||
nsIWebSocket.idl \
|
||||
nsIEventSource.idl \
|
||||
$(NULL)
|
||||
|
||||
|
@ -134,10 +134,6 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
indexedDB::FileInfo*
|
||||
GetFileInfoInternal(indexedDB::FileManager* aFileManager,
|
||||
PRUint32 aStartIndex);
|
||||
|
||||
bool mIsFile;
|
||||
bool mImmutable;
|
||||
nsString mContentType;
|
||||
|
@ -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;
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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'");
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -500,7 +500,7 @@ DOMCI_CLASS(DesktopNotification)
|
||||
DOMCI_CLASS(DesktopNotificationCenter)
|
||||
|
||||
// WebSocket
|
||||
DOMCI_CLASS(MozWebSocket)
|
||||
DOMCI_CLASS(WebSocket)
|
||||
DOMCI_CLASS(CloseEvent)
|
||||
|
||||
DOMCI_CLASS(IDBFactory)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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) \
|
||||
{ } \
|
||||
\
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -71,6 +71,7 @@ CPPSRCS = \
|
||||
LazyIdleThread.cpp \
|
||||
OpenDatabaseHelper.cpp \
|
||||
TransactionThreadPool.cpp \
|
||||
Key.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_mozilla/dom/indexedDB = \
|
||||
|
@ -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!");
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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>
|
@ -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) {
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
87
dom/indexedDB/test/test_file_put_get_object.html
Normal 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>
|