Merge last green PGO from inbound to central

This commit is contained in:
Marco Bonardo 2012-02-25 11:11:15 +01:00
commit 486fa4d538
247 changed files with 5443 additions and 4685 deletions

View File

@ -60,7 +60,7 @@ namespace statistics {
{
static bool firstTime = true;
if (firstTime) {
Telemetry::Accumulate(Telemetry::ISIMPLE_DOM_USAGE, 1);
Telemetry::Accumulate(Telemetry::A11Y_ISIMPLEDOM_USAGE, 1);
firstTime = false;
}
}
@ -69,13 +69,13 @@ namespace statistics {
* Report that IAccessibleTable has been used.
*/
inline void IAccessibleTableUsed()
{ Telemetry::Accumulate(Telemetry::IACCESSIBLE_TABLE_USAGE, 1); }
{ Telemetry::Accumulate(Telemetry::A11Y_IATABLE_USAGE, 1); }
/**
* Report that XForms accessibility has been instantiated.
*/
inline void XFormsAccessibleUsed()
{ Telemetry::Accumulate(Telemetry::XFORMS_ACCESSIBLE_USED, 1); }
{ Telemetry::Accumulate(Telemetry::A11Y_XFORMS_USAGE, 1); }
} // namespace statistics
} // namespace a11y

View File

@ -136,7 +136,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
"combobox",
roles::COMBOBOX,
kUseMapRole,
eHasValueMinMax,
eNoValue,
eOpenCloseAction,
eNoLiveAttr,
states::COLLAPSED | states::HASPOPUP,

View File

@ -854,9 +854,10 @@ nsAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
nsDocAccessible* contentDocAcc = GetAccService()->
GetDocAccessible(content->OwnerDoc());
// contentDocAcc in some circumstances can be NULL
// See https://bugzilla.mozilla.org/show_bug.cgi?id=729861
NS_ENSURE_TRUE(contentDocAcc, fallbackAnswer);
// contentDocAcc in some circumstances can be NULL. See bug 729861
NS_ASSERTION(contentDocAcc, "could not get the document accessible");
if (!contentDocAcc)
return fallbackAnswer;
nsAccessible* accessible = contentDocAcc->GetAccessibleOrContainer(content);
if (!accessible)

View File

@ -1653,12 +1653,6 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
gPrefService.addObserver(ctrlTab.prefName, ctrlTab, false);
gPrefService.addObserver(allTabs.prefName, allTabs, false);
// Delayed initialization of the livemarks update timer.
// Livemark updates don't need to start until after bookmark UI
// such as the toolbar has initialized. Starting 5 seconds after
// delayedStartup in order to stagger this before the download manager starts.
setTimeout(function() PlacesUtils.livemarks.start(), 5000);
// Initialize the download manager some time after the app starts so that
// auto-resume downloads begin (such as after crashing or quitting with
// active downloads) and speeds up the first-load of the download manager UI.

View File

@ -225,6 +225,7 @@ _BROWSER_FILES = \
browser_tabs_owner.js \
browser_urlbarCopying.js \
browser_urlbarEnter.js \
browser_urlbarRevert.js \
browser_urlbarTrimURLs.js \
browser_urlHighlight.js \
browser_visibleFindSelection.js \

View File

@ -0,0 +1,29 @@
function test() {
waitForExplicitFinish();
let tab = gBrowser.addTab("http://example.com");
gBrowser.selectedTab = tab;
onLoad(function () {
let originalValue = gURLBar.value;
gBrowser.userTypedValue = "foobar";
gBrowser.selectedTab = gBrowser.tabs[0];
gBrowser.selectedTab = tab;
is(gURLBar.value, "foobar", "location bar displays typed value");
gURLBar.focus();
EventUtils.synthesizeKey("VK_ESCAPE", {});
is(gURLBar.value, originalValue, "ESC reverted the location bar value");
gBrowser.removeTab(tab);
finish();
});
}
function onLoad(callback) {
gBrowser.selectedBrowser.addEventListener("pageshow", function loadListener() {
gBrowser.selectedBrowser.removeEventListener("pageshow", loadListener, false);
executeSoon(callback);
});
}

View File

@ -45,6 +45,10 @@ const Cu = Components.utils;
const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC =
"distribution-customization-complete";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
function DistributionCustomizer() {
let dirSvc = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties);
@ -78,27 +82,6 @@ DistributionCustomizer.prototype = {
return this._locale;
},
get _bmSvc() {
let svc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
this.__defineGetter__("_bmSvc", function() svc);
return this._bmSvc;
},
get _annoSvc() {
let svc = Cc["@mozilla.org/browser/annotation-service;1"].
getService(Ci.nsIAnnotationService);
this.__defineGetter__("_annoSvc", function() svc);
return this._annoSvc;
},
get _livemarkSvc() {
let svc = Cc["@mozilla.org/browser/livemark-service;2"].
getService(Ci.nsILivemarkService);
this.__defineGetter__("_livemarkSvc", function() svc);
return this._livemarkSvc;
},
get _prefSvc() {
let svc = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService);
@ -167,7 +150,7 @@ DistributionCustomizer.prototype = {
if (!items[iid])
continue;
let index = this._bmSvc.DEFAULT_INDEX;
let index = PlacesUtils.bookmarks.DEFAULT_INDEX;
let newId;
switch (items[iid]["type"]) {
@ -178,23 +161,25 @@ DistributionCustomizer.prototype = {
if (iid < defaultItemId)
index = prependIndex++;
newId = this._bmSvc.createFolder(parentId, items[iid]["title"], index);
newId = PlacesUtils.bookmarks.createFolder(parentId,
items[iid]["title"],
index);
this._parseBookmarksSection(newId, "BookmarksFolder-" +
items[iid]["folderId"]);
if (items[iid]["description"])
this._annoSvc.setItemAnnotation(newId,
"bookmarkProperties/description",
items[iid]["description"], 0,
this._annoSvc.EXPIRE_NEVER);
PlacesUtils.annotations.setItemAnnotation(newId,
"bookmarkProperties/description",
items[iid]["description"], 0,
PlacesUtils.annotations.EXPIRE_NEVER);
break;
case "separator":
if (iid < defaultItemId)
index = prependIndex++;
this._bmSvc.insertSeparator(parentId, index);
PlacesUtils.bookmarks.insertSeparator(parentId, index);
break;
case "livemark":
@ -202,12 +187,12 @@ DistributionCustomizer.prototype = {
index = prependIndex++;
// Don't bother updating the livemark contents on creation.
newId = this._livemarkSvc.
createLivemarkFolderOnly(parentId,
items[iid]["title"],
this._makeURI(items[iid]["siteLink"]),
this._makeURI(items[iid]["feedLink"]),
index);
PlacesUtils.livemarks.addLivemark({ title: items[iid]["title"]
, parentId: parentId
, index: index
, feedURI: this._makeURI(items[iid]["feedLink"])
, siteURI: this._makeURI(items[iid]["siteLink"])
});
break;
case "bookmark":
@ -215,15 +200,15 @@ DistributionCustomizer.prototype = {
if (iid < defaultItemId)
index = prependIndex++;
newId = this._bmSvc.insertBookmark(parentId,
this._makeURI(items[iid]["link"]),
index, items[iid]["title"]);
newId = PlacesUtils.bookmarks.insertBookmark(parentId,
this._makeURI(items[iid]["link"]),
index, items[iid]["title"]);
if (items[iid]["description"])
this._annoSvc.setItemAnnotation(newId,
"bookmarkProperties/description",
items[iid]["description"], 0,
this._annoSvc.EXPIRE_NEVER);
PlacesUtils.annotations.setItemAnnotation(newId,
"bookmarkProperties/description",
items[iid]["description"], 0,
PlacesUtils.annotations.EXPIRE_NEVER);
break;
}
@ -277,10 +262,10 @@ DistributionCustomizer.prototype = {
if (!bmProcessed) {
if (sections["BookmarksMenu"])
this._parseBookmarksSection(this._bmSvc.bookmarksMenuFolder,
this._parseBookmarksSection(PlacesUtils.bookmarksMenuFolderId,
"BookmarksMenu");
if (sections["BookmarksToolbar"])
this._parseBookmarksSection(this._bmSvc.toolbarFolder,
this._parseBookmarksSection(PlacesUtils.toolbarFolderId,
"BookmarksToolbar");
this._prefs.setBoolPref(bmProcessedPref, true);
}

View File

@ -777,6 +777,15 @@ BrowserGlue.prototype = {
// This is used to reprompt users when privacy message changes
const TELEMETRY_PROMPT_REV = 2;
function appendTelemetryNotification(notifyBox, message, buttons, hideclose) {
let notification = notifyBox.appendNotification(message, "telemetry", null,
notifyBox.PRIORITY_INFO_LOW,
buttons);
notification.setAttribute("hideclose", hideclose);
notification.persistence = -1; // Until user closes it
return notification;
}
var telemetryPrompted = null;
try {
telemetryPrompted = Services.prefs.getIntPref(PREF_TELEMETRY_PROMPTED);
@ -823,10 +832,8 @@ BrowserGlue.prototype = {
// Set pref to indicate we've shown the notification.
Services.prefs.setIntPref(PREF_TELEMETRY_PROMPTED, TELEMETRY_PROMPT_REV);
var notification = notifyBox.appendNotification(telemetryPrompt, "telemetry", null, notifyBox.PRIORITY_INFO_LOW, buttons);
notification.setAttribute("hideclose", true);
notification.persistence = -1; // Until user closes it
let notification = appendTelemetryNotification(notifyBox, telemetryPrompt,
buttons, true);
let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let link = notification.ownerDocument.createElementNS(XULNS, "label");
link.className = "text-link telemetry-text-link";
@ -838,8 +845,7 @@ BrowserGlue.prototype = {
notification.parentNode.removeNotification(notification, true);
// Add a new notification to that tab, with no "Learn more" link
notifyBox = browser.getNotificationBox();
notification = notifyBox.appendNotification(telemetryPrompt, "telemetry", null, notifyBox.PRIORITY_INFO_LOW, buttons);
notification.persistence = -1; // Until user closes it
appendTelemetryNotification(notifyBox, telemetryPrompt, buttons, true);
}, false);
let description = notification.ownerDocument.getAnonymousElementByAttribute(notification, "anonid", "messageText");
description.appendChild(link);
@ -1300,7 +1306,7 @@ BrowserGlue.prototype = {
// be set to the version it has been added in, we will compare its value
// to users' smartBookmarksVersion and add new smart bookmarks without
// recreating old deleted ones.
const SMART_BOOKMARKS_VERSION = 2;
const SMART_BOOKMARKS_VERSION = 3;
const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion";
@ -1346,7 +1352,6 @@ BrowserGlue.prototype = {
Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
"&sort=" +
Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
"&excludeItemIfParentHasAnnotation=livemark%2FfeedURI" +
"&maxResults=" + MAX_RESULTS +
"&excludeQueries=1"),
parent: PlacesUtils.bookmarksMenuFolderId,

View File

@ -281,13 +281,26 @@ var BookmarkPropertiesPanel = {
break;
case "folder":
if (PlacesUtils.itemIsLivemark(this._itemId)) {
this._itemType = LIVEMARK_CONTAINER;
this._feedURI = PlacesUtils.livemarks.getFeedURI(this._itemId);
this._siteURI = PlacesUtils.livemarks.getSiteURI(this._itemId);
}
else
this._itemType = BOOKMARK_FOLDER;
this._itemType = BOOKMARK_FOLDER;
PlacesUtils.livemarks.getLivemark(
{ id: this._itemId },
(function (aStatus, aLivemark) {
if (Components.isSuccessCode(aStatus)) {
this._itemType = LIVEMARK_CONTAINER;
this._feedURI = aLivemark.feedURI;
this._siteURI = aLivemark.siteURI;
this._fillEditProperties();
let acceptButton = document.documentElement.getButton("accept");
acceptButton.disabled = !this._inputIsValid();
let newHeight = window.outerHeight +
this._element("descriptionField").boxObject.height;
window.resizeTo(window.outerWidth, newHeight);
}
}).bind(this)
);
break;
}
@ -341,8 +354,7 @@ var BookmarkPropertiesPanel = {
this._fillAddProperties();
// if this is an uri related dialog disable accept button until
// the user fills an uri value.
if (this._itemType == BOOKMARK_ITEM ||
this._itemType == LIVEMARK_CONTAINER)
if (this._itemType == BOOKMARK_ITEM)
acceptButton.disabled = !this._inputIsValid();
break;
}
@ -518,16 +530,6 @@ var BookmarkPropertiesPanel = {
if (this._isAddKeywordDialog && !this._element("keywordField").value.length)
return false;
// Feed Location has to be a valid URI;
// Site Location has to be a valid URI or empty
if (this._itemType == LIVEMARK_CONTAINER) {
if (!this._containsValidURI("feedLocationField"))
return false;
if (!this._containsValidURI("siteLocationField") &&
(this._element("siteLocationField").value.length > 0))
return false;
}
return true;
},

View File

@ -1,44 +1,6 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Places Frontend Code.
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2005
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Annie Sullivan <annie.sullivan@gmail.com>
* Ben Goodger <beng@google.com>
* Myk Melez <myk@mozilla.org>
* Marco Bonardo <mak77@bonardo.net>
* Asaf Romano <mano@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
* 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 ***** */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
@ -170,7 +132,8 @@ PlacesViewBase.prototype = {
let selectedNode = this.selectedNode;
if (selectedNode) {
let popup = document.popupNode;
if (!popup._placesNode || popup._placesNode == this._resultNode) {
if (!popup._placesNode || popup._placesNode == this._resultNode ||
popup._placesNode.itemId == -1) {
// If a static menuitem is selected, or if the root node is selected,
// the insertion point is inside the folder, at the end.
container = selectedNode;
@ -210,7 +173,9 @@ PlacesViewBase.prototype = {
let end = aPopup._endMarker != -1 ? aPopup._endMarker :
aPopup.childNodes.length;
let items = [];
let placesNodeFound = false;
// Automatically adjust the start and the end markers.
let firstNonStaticNodeFound = false;
for (let i = start; i < end; ++i) {
let item = aPopup.childNodes[i];
if (item.getAttribute("builder") == "end") {
@ -220,18 +185,20 @@ PlacesViewBase.prototype = {
aPopup._endMarker = i;
break;
}
if (item._placesNode) {
items.push(item);
placesNodeFound = true;
firstNonStaticNodeFound = true;
}
else {
// This is static content...
if (!placesNodeFound)
// ...at the start of the popup
// Initialized in menu.xml, in the base binding
// This is static content.
if (!firstNonStaticNodeFound) {
// We are at the beginning of the popup, in static content.
// The markers are initialized in menu.xml, in the base binding.
aPopup._startMarker++;
}
else {
// ...after places nodes
// We are at the end of the popup, after places nodes
aPopup._endMarker = i;
break;
}
@ -248,15 +215,20 @@ PlacesViewBase.prototype = {
_rebuildPopup: function PVB__rebuildPopup(aPopup) {
this._cleanPopup(aPopup);
// If this is a livemark container check if the status menuitem has
// to be added or removed.
if (PlacesUtils.nodeIsLivemarkContainer(aPopup._placesNode))
this._ensureLivemarkStatusMenuItem(aPopup);
let resultNode = aPopup._placesNode;
if (!resultNode.containerOpen)
return;
if (resultNode._feedURI) {
aPopup.removeAttribute("emptyplacesresult");
if (aPopup._emptyMenuItem) {
aPopup._emptyMenuItem.hidden = true;
}
aPopup._built = true;
this._populateLivemarkPopup(aPopup);
return;
}
let cc = resultNode.childCount;
if (cc > 0) {
aPopup.removeAttribute("emptyplacesresult");
@ -303,11 +275,14 @@ PlacesViewBase.prototype = {
_createMenuItemForPlacesNode:
function PVB__createMenuItemForPlacesNode(aPlacesNode) {
delete aPlacesNode._DOMElement;
let element;
let type = aPlacesNode.type;
if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR)
if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR) {
element = document.createElement("menuseparator");
}
else {
let itemId = aPlacesNode.itemId;
if (PlacesUtils.uriTypes.indexOf(type) != -1) {
element = document.createElement("menuitem");
element.className = "menuitem-iconic bookmark-item menuitem-with-favicon";
@ -327,9 +302,19 @@ PlacesViewBase.prototype = {
else if (PlacesUtils.nodeIsHost(aPlacesNode))
element.setAttribute("hostContainer", "true");
}
else if (aPlacesNode.itemId != -1) {
if (PlacesUtils.nodeIsLivemarkContainer(aPlacesNode))
element.setAttribute("livemark", "true");
else if (itemId != -1) {
PlacesUtils.livemarks.getLivemark(
{ id: itemId },
function (aStatus, aLivemark) {
if (Components.isSuccessCode(aStatus)) {
element.setAttribute("livemark", "true");
// Set an expando on the node, controller will use it to build
// its metadata.
aPlacesNode._feedURI = aLivemark.feedURI;
aPlacesNode._siteURI = aLivemark.siteURI;
}
}
);
}
let popup = document.createElement("menupopup");
@ -392,42 +377,84 @@ PlacesViewBase.prototype = {
return element;
},
_setLivemarkSiteURIMenuItem:
function PVB__setLivemarkSiteURIMenuItem(aPopup) {
let siteUrl = aPopup._placesNode._siteURI ? aPopup._placesNode._siteURI.spec
: null;
if (!siteUrl && aPopup._siteURIMenuitem) {
aPopup.removeChild(aPopup._siteURIMenuitem);
aPopup._siteURIMenuitem = null;
aPopup._startMarker--;
aPopup.removeChild(aPopup._siteURIMenuseparator);
aPopup._siteURIMenuseparator = null;
aPopup._startMarker--;
}
else if (siteUrl && !aPopup._siteURIMenuitem) {
// Add "Open (Feed Name)" menuitem.
aPopup._siteURIMenuitem = document.createElement("menuitem");
aPopup._siteURIMenuitem.className = "openlivemarksite-menuitem";
aPopup._siteURIMenuitem.setAttribute("targetURI", siteUrl);
aPopup._siteURIMenuitem.setAttribute("oncommand",
"openUILink(this.getAttribute('targetURI'), event);");
// If a user middle-clicks this item we serve the oncommand event.
// We are using checkForMiddleClick because of Bug 246720.
// Note: stopPropagation is needed to avoid serving middle-click
// with BT_onClick that would open all items in tabs.
aPopup._siteURIMenuitem.setAttribute("onclick",
"checkForMiddleClick(this, event); event.stopPropagation();");
let label =
PlacesUIUtils.getFormattedString("menuOpenLivemarkOrigin.label",
[aPopup.parentNode.getAttribute("label")])
aPopup._siteURIMenuitem.setAttribute("label", label);
aPopup.insertBefore(aPopup._siteURIMenuitem,
aPopup.childNodes.item(aPopup._startMarker + 1));
aPopup._startMarker++;
aPopup._siteURIMenuseparator = document.createElement("menuseparator");
aPopup.insertBefore(aPopup._siteURIMenuseparator,
aPopup.childNodes.item(aPopup._startMarker + 1));
aPopup._startMarker++;
}
},
/**
* Add, update or remove the livemark status menuitem.
* @param aPopup
* The livemark container popup
* @param aStatus
* The livemark status
*/
_ensureLivemarkStatusMenuItem:
function PVB_ensureLivemarkStatusMenuItem(aPopup) {
_setLivemarkStatusMenuItem:
function PVB_setLivemarkStatusMenuItem(aPopup, aStatus) {
let itemId = aPopup._placesNode.itemId;
let as = PlacesUtils.annotations;
let statusMenuitem = aPopup._statusMenuitem;
let stringId = "";
if (aStatus == Ci.mozILivemark.STATUS_LOADING)
stringId = "bookmarksLivemarkLoading";
else if (aStatus == Ci.mozILivemark.STATUS_FAILED)
stringId = "bookmarksLivemarkFailed";
let lmStatus = null;
if (as.itemHasAnnotation(itemId, PlacesUtils.LMANNO_LOADFAILED))
lmStatus = "bookmarksLivemarkFailed";
else if (as.itemHasAnnotation(itemId, PlacesUtils.LMANNO_LOADING))
lmStatus = "bookmarksLivemarkLoading";
let lmStatusElt = aPopup._lmStatusMenuItem;
if (lmStatus && !lmStatusElt) {
if (stringId && !statusMenuitem) {
// Create the status menuitem and cache it in the popup object.
lmStatusElt = document.createElement("menuitem");
lmStatusElt.setAttribute("lmStatus", lmStatus);
lmStatusElt.setAttribute("label", PlacesUIUtils.getString(lmStatus));
lmStatusElt.setAttribute("disabled", true);
aPopup.insertBefore(lmStatusElt,
statusMenuitem = document.createElement("menuitem");
statusMenuitem.setAttribute("livemarkStatus", stringId);
statusMenuitem.setAttribute("label", PlacesUIUtils.getString(stringId));
statusMenuitem.setAttribute("disabled", true);
aPopup.insertBefore(statusMenuitem,
aPopup.childNodes.item(aPopup._startMarker + 1));
aPopup._lmStatusMenuItem = lmStatusElt;
aPopup._statusMenuitem = statusMenuitem;
aPopup._startMarker++;
}
else if (lmStatus && lmStatusElt.getAttribute("lmStatus") != lmStatus) {
else if (stringId &&
statusMenuitem.getAttribute("livemarkStatus") != stringId) {
// Status has changed, update the cached status menuitem.
lmStatusElt.setAttribute("label", this.getString(lmStatus));
statusMenuitem.setAttribute("label", PlacesUIUtils.getString(stringId));
}
else if (!lmStatus && lmStatusElt) {
// No status, remove the cached menuitem.
aPopup.removeChild(aPopup._lmStatusMenuItem);
aPopup._lmStatusMenuItem = null;
else if (!stringId && statusMenuitem) {
// The livemark has finished loading.
aPopup.removeChild(aPopup._statusMenuitem);
aPopup._statusMenuitem = null;
aPopup._startMarker--;
}
},
@ -488,14 +515,22 @@ PlacesViewBase.prototype = {
// being modified.
if (aAnno == PlacesUtils.LMANNO_FEEDURI) {
let menu = elt.parentNode;
if (!menu.hasAttribute("livemark"))
if (!menu.hasAttribute("livemark")) {
menu.setAttribute("livemark", "true");
}
}
if ([PlacesUtils.LMANNO_LOADING,
PlacesUtils.LMANNO_LOADFAILED].indexOf(aAnno) != -1) {
// Loading status changed, update the livemark status menuitem.
this._ensureLivemarkStatusMenuItem(elt);
PlacesUtils.livemarks.getLivemark(
{ id: aPlacesNode.itemId },
(function (aStatus, aLivemark) {
if (Components.isSuccessCode(aStatus)) {
// Set an expando on the node, controller will use it to build
// its metadata.
aPlacesNode._feedURI = aLivemark.feedURI;
aPlacesNode._siteURI = aLivemark.siteURI;
this.invalidateContainer(aPlacesNode);
}
}).bind(this)
);
}
},
@ -580,7 +615,24 @@ PlacesViewBase.prototype = {
}
},
nodeHistoryDetailsChanged: function() { },
nodeHistoryDetailsChanged:
function PVB_nodeHistoryDetailsChanged(aPlacesNode, aTime, aCount) {
if (aPlacesNode.parent && aPlacesNode.parent._feedURI) {
// Find the node in the parent.
let popup = aPlacesNode.parent._DOMElement;
for (let i = popup._startMarker; i < popup.childNodes.length; i++) {
let child = popup.childNodes[i];
if (child._placesNode && child._placesNode.uri == aPlacesNode.uri) {
if (aCount)
child.setAttribute("visited", "true");
else
child.removeAttribute("visited");
break;
}
}
}
},
nodeTagsChanged: function() { },
nodeDateAddedChanged: function() { },
nodeLastModifiedChanged: function() { },
@ -642,10 +694,60 @@ PlacesViewBase.prototype = {
if (aNewState == Ci.nsINavHistoryContainerResultNode.STATE_OPENED ||
aNewState == Ci.nsINavHistoryContainerResultNode.STATE_CLOSED) {
this.invalidateContainer(aPlacesNode);
if (PlacesUtils.nodeIsFolder(aPlacesNode)) {
let queryOptions = PlacesUtils.asQuery(this._result.root).queryOptions;
if (queryOptions.excludeItems) {
return;
}
PlacesUtils.livemarks.getLivemark({ id: aPlacesNode.itemId },
(function (aStatus, aLivemark) {
if (Components.isSuccessCode(aStatus)) {
let shouldInvalidate = !aPlacesNode._feedURI;
aPlacesNode._feedURI = aLivemark.feedURI;
aPlacesNode._siteURI = aLivemark.siteURI;
if (aNewState == Ci.nsINavHistoryContainerResultNode.STATE_OPENED) {
aLivemark.registerForUpdates(aPlacesNode, this);
aLivemark.reload();
if (shouldInvalidate)
this.invalidateContainer(aPlacesNode);
}
else {
aLivemark.unregisterForUpdates(aPlacesNode);
}
}
}).bind(this)
);
}
}
else {
throw "Unexpected state passed to containerStateChanged";
}
},
_populateLivemarkPopup: function PVB__populateLivemarkPopup(aPopup)
{
this._setLivemarkSiteURIMenuItem(aPopup);
this._setLivemarkStatusMenuItem(aPopup, Ci.mozILivemark.STATUS_LOADING);
PlacesUtils.livemarks.getLivemark({ id: aPopup._placesNode.itemId },
(function (aStatus, aLivemark) {
let placesNode = aPopup._placesNode;
if (!Components.isSuccessCode(aStatus) || !placesNode.containerOpen)
return;
this._setLivemarkStatusMenuItem(aPopup, aLivemark.status);
this._cleanPopup(aPopup);
let children = aLivemark.getNodesForContainer(placesNode);
for (let i = 0; i < children.length; i++) {
let child = children[i];
this.nodeInserted(placesNode, child, i);
if (child.accessCount)
child._DOMElement.setAttribute("visited", true);
else
child._DOMElement.removeAttribute("visited");
}
}).bind(this)
);
},
invalidateContainer: function PVB_invalidateContainer(aPlacesNode) {
@ -696,77 +798,44 @@ PlacesViewBase.prototype = {
if (aPopup == this._rootElt)
return;
// Check if the popup contains at least 2 menuitems with places nodes
let numURINodes = 0;
let currentChild = aPopup.firstChild;
while (currentChild) {
if (currentChild.localName == "menuitem" && currentChild._placesNode) {
if (++numURINodes == 2)
break;
let hasMultipleURIs = false;
// Check if the popup contains at least 2 menuitems with places nodes.
// We don't currently support opening multiple uri nodes when they are not
// populated by the result.
if (aPopup._placesNode.childCount > 0) {
let currentChild = aPopup.firstChild;
let numURINodes = 0;
while (currentChild) {
if (currentChild.localName == "menuitem" && currentChild._placesNode) {
if (++numURINodes == 2)
break;
}
currentChild = currentChild.nextSibling;
}
currentChild = currentChild.nextSibling;
hasMultipleURIs = numURINodes > 1;
}
let hasMultipleURIs = numURINodes > 1;
let itemId = aPopup._placesNode.itemId;
let siteURIString = "";
if (itemId != -1 && PlacesUtils.itemIsLivemark(itemId)) {
let siteURI = PlacesUtils.livemarks.getSiteURI(itemId);
if (siteURI)
siteURIString = siteURI.spec;
}
if (!siteURIString && aPopup._endOptOpenSiteURI) {
aPopup.removeChild(aPopup._endOptOpenSiteURI);
aPopup._endOptOpenSiteURI = null;
}
if (!hasMultipleURIs && aPopup._endOptOpenAllInTabs) {
aPopup.removeChild(aPopup._endOptOpenAllInTabs);
aPopup._endOptOpenAllInTabs = null;
}
if (!(hasMultipleURIs || siteURIString)) {
if (!hasMultipleURIs) {
// We don't have to show any option.
if (aPopup._endOptSeparator) {
if (aPopup._endOptOpenAllInTabs) {
aPopup.removeChild(aPopup._endOptOpenAllInTabs);
aPopup._endOptOpenAllInTabs = null;
aPopup._endMarker--;
aPopup.removeChild(aPopup._endOptSeparator);
aPopup._endOptSeparator = null;
aPopup._endMarker = -1;
aPopup._endMarker--;
}
return;
}
if (!aPopup._endOptSeparator) {
else if (!aPopup._endOptOpenAllInTabs) {
// Create a separator before options.
aPopup._endOptSeparator = document.createElement("menuseparator");
aPopup._endOptSeparator.className = "bookmarks-actions-menuseparator";
aPopup._endMarker = aPopup.childNodes.length;
aPopup.appendChild(aPopup._endOptSeparator);
}
aPopup._endMarker++;
if (siteURIString && !aPopup._endOptOpenSiteURI) {
// Add "Open (Feed Name)" menuitem if it's a livemark with a siteURI.
aPopup._endOptOpenSiteURI = document.createElement("menuitem");
aPopup._endOptOpenSiteURI.className = "openlivemarksite-menuitem";
aPopup._endOptOpenSiteURI.setAttribute("targetURI", siteURIString);
aPopup._endOptOpenSiteURI.setAttribute("oncommand",
"openUILink(this.getAttribute('targetURI'), event);");
// If a user middle-clicks this item we serve the oncommand event
// We are using checkForMiddleClick because of Bug 246720
// Note: stopPropagation is needed to avoid serving middle-click
// with BT_onClick that would open all items in tabs.
aPopup._endOptOpenSiteURI.setAttribute("onclick",
"checkForMiddleClick(this, event); event.stopPropagation();");
aPopup._endOptOpenSiteURI.setAttribute("label",
PlacesUIUtils.getFormattedString("menuOpenLivemarkOrigin.label",
[aPopup.parentNode.getAttribute("label")]));
aPopup.appendChild(aPopup._endOptOpenSiteURI);
}
if (hasMultipleURIs && !aPopup._endOptOpenAllInTabs) {
// Add the "Open All in Tabs" menuitem if there are
// at least two menuitems with places result nodes.
// Add the "Open All in Tabs" menuitem.
aPopup._endOptOpenAllInTabs = document.createElement("menuitem");
aPopup._endOptOpenAllInTabs.className = "openintabs-menuitem";
aPopup._endOptOpenAllInTabs.setAttribute("oncommand",
@ -777,6 +846,7 @@ PlacesViewBase.prototype = {
aPopup._endOptOpenAllInTabs.setAttribute("label",
gNavigatorBundle.getString("menuOpenAllInTabs.label"));
aPopup.appendChild(aPopup._endOptOpenAllInTabs);
aPopup._endMarker++;
}
},
@ -901,6 +971,7 @@ PlacesToolbar.prototype = {
_insertNewItem:
function PT__insertNewItem(aChild, aBefore) {
delete aChild._DOMElement;
let type = aChild.type;
let button;
if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR) {
@ -923,8 +994,19 @@ PlacesToolbar.prototype = {
if (PlacesUtils.nodeIsTagQuery(aChild))
button.setAttribute("tagContainer", "true");
}
else if (PlacesUtils.nodeIsLivemarkContainer(aChild)) {
button.setAttribute("livemark", "true");
else if (PlacesUtils.nodeIsFolder(aChild)) {
PlacesUtils.livemarks.getLivemark(
{ id: aChild.itemId },
function (aStatus, aLivemark) {
if (Components.isSuccessCode(aStatus)) {
button.setAttribute("livemark", "true");
// Set an expando on the node, controller will use it to build
// its metadata.
aChild._feedURI = aLivemark.feedURI;
aChild._siteURI = aLivemark.siteURI;
}
}
);
}
let popup = document.createElement("menupopup");
@ -1188,12 +1270,19 @@ PlacesToolbar.prototype = {
// All livemarks have a feedURI, so use it as our indicator.
if (aAnno == PlacesUtils.LMANNO_FEEDURI) {
elt.setAttribute("livemark", true);
}
if ([PlacesUtils.LMANNO_LOADING,
PlacesUtils.LMANNO_LOADFAILED].indexOf(aAnno) != -1) {
// Loading status changed, update the livemark status menuitem.
this._ensureLivemarkStatusMenuItem(elt.firstChild);
PlacesUtils.livemarks.getLivemark(
{ id: aPlacesNode.itemId },
(function (aStatus, aLivemark) {
if (Components.isSuccessCode(aStatus)) {
// Set an expando on the node, controller will use it to build
// its metadata.
aPlacesNode._feedURI = aLivemark.feedURI;
aPlacesNode._siteURI = aLivemark.siteURI;
this.invalidateContainer(aPlacesNode);
}
}).bind(this)
);
}
}
else {
@ -1623,13 +1712,16 @@ PlacesToolbar.prototype = {
_onPopupHidden: function PT__onPopupHidden(aEvent) {
let popup = aEvent.target;
let placesNode = popup._placesNode;
// Avoid handling popuphidden of inner views
if (popup._placesNode && PlacesUIUtils.getViewForNode(popup) == this) {
if (placesNode && PlacesUIUtils.getViewForNode(popup) == this) {
// UI performance: folder queries are cheap, keep the resultnode open
// so we don't rebuild its contents whenever the popup is reopened.
if (!PlacesUtils.nodeIsFolder(popup._placesNode))
popup._placesNode.containerOpen = false;
// Though, we want to always close feed containers so their expiration
// status will be checked at next opening.
if (!PlacesUtils.nodeIsFolder(placesNode) || placesNode._feedURI) {
placesNode.containerOpen = false;
}
}
let parent = popup.parentNode;

View File

@ -44,7 +44,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
// XXXmano: we should move most/all of these constants to PlacesUtils
const ORGANIZER_ROOT_BOOKMARKS = "place:folder=BOOKMARKS_MENU&excludeItems=1&queryType=1";
const ORGANIZER_SUBSCRIPTIONS_QUERY = "place:annotation=livemark%2FfeedURI";
// No change to the view, preserve current selection
const RELOAD_ACTION_NOTHING = 0;
@ -208,15 +207,11 @@ PlacesController.prototype = {
Ci.nsINavHistoryQueryOptions.SORT_BY_NONE;
case "placesCmd_show:info":
var selectedNode = this._view.selectedNode;
if (selectedNode &&
PlacesUtils.getConcreteItemId(selectedNode) != -1 &&
!PlacesUtils.nodeIsLivemarkItem(selectedNode))
return true;
return false;
return selectedNode && PlacesUtils.getConcreteItemId(selectedNode) != -1
case "placesCmd_reload":
// Livemark containers
var selectedNode = this._view.selectedNode;
return selectedNode && PlacesUtils.nodeIsLivemarkContainer(selectedNode);
return selectedNode && !!selectedNode._feedURI;
case "placesCmd_sortBy:name":
var selectedNode = this._view.selectedNode;
return selectedNode &&
@ -509,7 +504,7 @@ PlacesController.prototype = {
if (parentNode) {
if (PlacesUtils.nodeIsTagQuery(parentNode))
nodeData["tagChild"] = true;
else if (PlacesUtils.nodeIsLivemarkContainer(parentNode))
else if (parentNode._feedURI)
nodeData["livemarkChild"] = true;
}
}
@ -734,8 +729,17 @@ PlacesController.prototype = {
*/
reloadSelectedLivemark: function PC_reloadSelectedLivemark() {
var selectedNode = this._view.selectedNode;
if (selectedNode && PlacesUtils.nodeIsLivemarkContainer(selectedNode))
PlacesUtils.livemarks.reloadLivemarkFolder(selectedNode.itemId);
if (selectedNode) {
let itemId = selectedNode.itemId;
PlacesUtils.livemarks.getLivemark(
{ id: itemId },
(function(aStatus, aLivemark) {
if (Components.isSuccessCode(aStatus)) {
aLivemark.reload(true);
}
}).bind(this)
);
}
},
/**
@ -1065,10 +1069,12 @@ PlacesController.prototype = {
addData(PlacesUtils.TYPE_X_MOZ_PLACE, i);
// Drop the feed uri for livemark containers
if (PlacesUtils.nodeIsLivemarkContainer(node))
addURIData(i, PlacesUtils.livemarks.getFeedURI(node.itemId).spec);
else if (node.uri)
if (node._feedURI) {
addURIData(i, node._feedURI.spec);
}
else if (node.uri) {
addURIData(i);
}
}
}
finally {
@ -1138,8 +1144,7 @@ PlacesController.prototype = {
if (PlacesUtils.nodeIsFolder(node))
copiedFolders.push(node);
let overrideURI = PlacesUtils.nodeIsLivemarkContainer(node) ?
PlacesUtils.livemarks.getFeedURI(node.itemId).spec : null;
let overrideURI = node._feedURI ? node._feedURI.spec : null;
let resolveShortcuts = !PlacesControllerDragHelper.canMoveNode(node);
contents.forEach(function (content) {

View File

@ -1,39 +1,6 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Places Bookmark Properties dialog.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Asaf Romano <mano@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
* 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 ***** */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
const LAST_USED_ANNO = "bookmarkPropertiesDialog/folderLastUsed";
const MAX_FOLDER_ITEM_IN_MENU_LIST = 5;
@ -52,6 +19,7 @@ var gEditItemOverlay = {
_observersAdded: false,
_staticFoldersListBuilt: false,
_initialized: false,
_titleOverride: "",
// the first field which was edited after this panel was initialized for
// a certain item
@ -80,6 +48,8 @@ var gEditItemOverlay = {
this._hiddenRows.splice(0, this._hiddenRows.length);
// force-read-only
this._readOnly = aInfo && aInfo.forceReadOnly;
this._titleOverride = aInfo && aInfo.titleOverride ? aInfo.titleOverride
: "";
},
_showHideRows: function EIO__showHideRows() {
@ -160,32 +130,34 @@ var gEditItemOverlay = {
}
else {
this._itemId = aFor;
// We can't store information on invalid itemIds.
this._readOnly = this._readOnly || this._itemId == -1;
var containerId = PlacesUtils.bookmarks.getFolderIdForItem(this._itemId);
this._itemType = PlacesUtils.bookmarks.getItemType(this._itemId);
if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK) {
this._uri = PlacesUtils.bookmarks.getBookmarkURI(this._itemId);
if (!this._readOnly) // If readOnly wasn't forced through aInfo
this._readOnly = PlacesUtils.itemIsLivemark(containerId);
this._initTextField("keywordField",
PlacesUtils.bookmarks
.getKeywordForBookmark(this._itemId));
// Load In Sidebar checkbox
this._element("loadInSidebarCheckbox").checked =
PlacesUtils.annotations.itemHasAnnotation(this._itemId,
PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO);
}
else {
if (!this._readOnly) // If readOnly wasn't forced through aInfo
this._readOnly = false;
this._uri = null;
this._isLivemark = PlacesUtils.itemIsLivemark(this._itemId);
if (this._isLivemark) {
var feedURI = PlacesUtils.livemarks.getFeedURI(this._itemId);
var siteURI = PlacesUtils.livemarks.getSiteURI(this._itemId);
this._initTextField("feedLocationField", feedURI.spec);
this._initTextField("siteLocationField", siteURI ? siteURI.spec : "");
}
this._isLivemark = false;
PlacesUtils.livemarks.getLivemark(
{id: this._itemId },
(function (aStatus, aLivemark) {
if (Components.isSuccessCode(aStatus)) {
this._isLivemark = true;
this._initTextField("feedLocationField", aLivemark.feedURI.spec, true);
this._initTextField("siteLocationField", aLivemark.siteURI ? aLivemark.siteURI.spec : "", true);
this._showHideRows();
}
}).bind(this)
);
}
// folder picker
@ -379,10 +351,17 @@ var gEditItemOverlay = {
},
_getItemStaticTitle: function EIO__getItemStaticTitle() {
if (this._itemId == -1)
return PlacesUtils.history.getPageTitle(this._uri);
if (this._titleOverride)
return this._titleOverride;
return PlacesUtils.bookmarks.getItemTitle(this._itemId);
let title = "";
if (this._itemId == -1) {
title = PlacesUtils.history.getPageTitle(this._uri);
}
else {
title = PlacesUtils.bookmarks.getItemTitle(this._itemId);
}
return title;
},
_initNamePicker: function EIO_initNamePicker() {
@ -425,6 +404,8 @@ var gEditItemOverlay = {
this._multiEdit = false;
this._firstEditedField = "";
this._initialized = false;
this._titleOverride = "";
this._readOnly = false;
},
onTagsFieldBlur: function EIO_onTagsFieldBlur() {
@ -597,36 +578,6 @@ var gEditItemOverlay = {
}
},
onFeedLocationFieldBlur: function EIO_onFeedLocationFieldBlur() {
var uri;
try {
uri = PlacesUIUtils.createFixedURI(this._element("feedLocationField").value);
}
catch(ex) { return; }
var currentFeedURI = PlacesUtils.livemarks.getFeedURI(this._itemId);
if (!currentFeedURI.equals(uri)) {
var txn = PlacesUIUtils.ptm.editLivemarkFeedURI(this._itemId, uri);
PlacesUIUtils.ptm.doTransaction(txn);
}
},
onSiteLocationFieldBlur: function EIO_onSiteLocationFieldBlur() {
var uri = null;
try {
uri = PlacesUIUtils.createFixedURI(this._element("siteLocationField").value);
}
catch(ex) { }
var currentSiteURI = PlacesUtils.livemarks.getSiteURI(this._itemId);
if ((!uri && !currentSiteURI) ||
(uri && currentSiteURI && currentSiteURI.equals(uri))) {
return;
}
var txn = PlacesUIUtils.ptm.editLivemarkSiteURI(this._itemId, uri);
PlacesUIUtils.ptm.doTransaction(txn);
},
onLoadInSidebarCheckboxCommand:
function EIO_onLoadInSidebarCheckboxCommand() {
var loadInSidebarChecked = this._element("loadInSidebarCheckbox").checked;
@ -1019,15 +970,19 @@ var gEditItemOverlay = {
PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO);
break;
case PlacesUtils.LMANNO_FEEDURI:
var feedURISpec = PlacesUtils.livemarks.getFeedURI(this._itemId).spec;
this._initTextField("feedLocationField", feedURISpec);
let feedURISpec =
PlacesUtils.annotations.getItemAnnotation(this._itemId,
PlacesUtils.LMANNO_FEEDURI);
this._initTextField("feedLocationField", feedURISpec, true);
break;
case PlacesUtils.LMANNO_SITEURI:
var siteURISpec = "";
var siteURI = PlacesUtils.livemarks.getSiteURI(this._itemId);
if (siteURI)
siteURISpec = siteURI.spec;
this._initTextField("siteLocationField", siteURISpec);
let siteURISpec = "";
try {
siteURISpec =
PlacesUtils.annotations.getItemAnnotation(this._itemId,
PlacesUtils.LMANNO_SITEURI);
} catch (ex) {}
this._initTextField("siteLocationField", siteURISpec, true);
break;
}
},

View File

@ -600,9 +600,7 @@ var PlacesOrganizer = {
return;
}
if (aNode.itemId != -1 &&
((PlacesUtils.nodeIsFolder(aNode) &&
!PlacesUtils.nodeIsLivemarkContainer(aNode)) ||
PlacesUtils.nodeIsLivemarkItem(aNode))) {
PlacesUtils.nodeIsFolder(aNode) && !aNode._feedURI) {
if (infoBox.getAttribute("minimal") == "true")
infoBox.setAttribute("wasminimal", "true");
infoBox.removeAttribute("minimal");
@ -688,8 +686,10 @@ var PlacesOrganizer = {
else
itemId = PlacesUtils._uri(aSelectedNode.uri);
gEditItemOverlay.initPanel(itemId, { hiddenRows: ["folderPicker"],
forceReadOnly: readOnly });
gEditItemOverlay.initPanel(itemId, { hiddenRows: ["folderPicker"]
, forceReadOnly: readOnly
, titleOverride: aSelectedNode.title
});
// Dynamically generated queries, like history date containers, have
// itemId !=0 and do not exist in history. For them the panel is

View File

@ -1,41 +1,6 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla History System
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2005
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brett Wilson <brettw@gmail.com> (Original author)
* Asaf Romano <mano@mozilla.com> (JavaScript version)
*
* 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 ***** */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
function PlacesTreeView(aFlatList, aOnOpenFlatContainer) {
this._tree = null;
@ -129,6 +94,10 @@ PlacesTreeView.prototype = {
if (aContainer._plainContainer !== undefined)
return aContainer._plainContainer;
// Livemarks are always plain containers.
if (aContainer._feedURI)
return aContainer._plainContainer = true;
// We don't know enough about non-query containers.
if (!(aContainer instanceof Ci.nsINavHistoryQueryResultNode))
return aContainer._plainContainer = false;
@ -328,7 +297,8 @@ PlacesTreeView.prototype = {
// Recursively do containers.
if (!this._flatList &&
curChild instanceof Ci.nsINavHistoryContainerResultNode) {
curChild instanceof Ci.nsINavHistoryContainerResultNode &&
!curChild._feedURI) {
let resource = this._getResourceForNode(curChild);
let isopen = resource != null &&
PlacesUIUtils.localStore.HasAssertion(resource,
@ -625,7 +595,8 @@ PlacesTreeView.prototype = {
// Compute the new row number of the node.
let row = -1;
if (aNewIndex == 0 || this._isPlainContainer(aParentNode)) {
let cc = aParentNode.childCount;
if (aNewIndex == 0 || this._isPlainContainer(aParentNode) || cc == 0) {
// We don't need to worry about sub hierarchies of the parent node
// if it's a plain container, or if the new node is its first child.
if (aParentNode == this._rootNode)
@ -638,7 +609,6 @@ PlacesTreeView.prototype = {
// can set the new visible index to be right before that. Note that we
// have to search down instead of up, because some siblings could have
// children themselves that would be in the way.
let cc = aParentNode.childCount;
let separatorsAreHidden = PlacesUtils.nodeIsSeparator(aNode) &&
this.isSorted();
for (let i = aNewIndex + 1; i < cc; i++) {
@ -664,8 +634,10 @@ PlacesTreeView.prototype = {
this._rows.splice(row, 0, aNode);
this._tree.rowCountChanged(row, 1);
if (PlacesUtils.nodeIsContainer(aNode) && PlacesUtils.asContainer(aNode).containerOpen)
if (PlacesUtils.nodeIsContainer(aNode) &&
PlacesUtils.asContainer(aNode).containerOpen) {
this.invalidateContainer(aNode);
}
},
/**
@ -814,6 +786,22 @@ PlacesTreeView.prototype = {
}
},
_populateLivemarkContainer: function PTV__populateLivemarkContainer(aNode) {
PlacesUtils.livemarks.getLivemark({ id: aNode.itemId },
(function (aStatus, aLivemark) {
let placesNode = aNode;
// Need to check containerOpen since getLivemark is async.
if (!Components.isSuccessCode(aStatus) || !placesNode.containerOpen)
return;
let children = aLivemark.getNodesForContainer(placesNode);
for (let i = 0; i < children.length; i++) {
let child = children[i];
this.nodeInserted(placesNode, child, i);
}
}).bind(this));
},
nodeTitleChanged: function PTV_nodeTitleChanged(aNode, aNewTitle) {
this._invalidateCellValue(aNode, this.COLUMN_TYPE_TITLE);
},
@ -829,6 +817,20 @@ PlacesTreeView.prototype = {
nodeHistoryDetailsChanged:
function PTV_nodeHistoryDetailsChanged(aNode, aUpdatedVisitDate,
aUpdatedVisitCount) {
if (aNode.parent && aNode.parent._feedURI) {
// Find the node in the parent.
let parentRow = this._flatList ? 0 : this._getRowForNode(aNode.parent);
for (let i = parentRow; i < this._rows.length; i++) {
let child = this.nodeForTreeIndex(i);
if (child.uri == aNode.uri) {
delete child._cellProperties;
this._invalidateCellValue(child, this.COLUMN_TYPE_TITLE);
break;
}
}
return;
}
this._invalidateCellValue(aNode, this.COLUMN_TYPE_DATE);
this._invalidateCellValue(aNode, this.COLUMN_TYPE_VISITCOUNT);
},
@ -844,9 +846,21 @@ PlacesTreeView.prototype = {
nodeAnnotationChanged: function PTV_nodeAnnotationChanged(aNode, aAnno) {
if (aAnno == PlacesUIUtils.DESCRIPTION_ANNO) {
this._invalidateCellValue(aNode, this.COLUMN_TYPE_DESCRIPTION);
} else if (aAnno == PlacesUtils.LMANNO_FEEDURI) {
// The livemark attribute is set as a cell property on the title cell.
this._invalidateCellValue(aNode, this.COLUMN_TYPE_TITLE);
}
else if (aAnno == PlacesUtils.LMANNO_FEEDURI) {
PlacesUtils.livemarks.getLivemark(
{ id: aNode.itemId },
(function (aStatus, aLivemark) {
if (Components.isSuccessCode(aStatus)) {
aNode._feedURI = aLivemark.feedURI;
if (aNode._cellProperties) {
aNode._cellProperties.push(this._getAtomFor("livemark"));
}
// The livemark attribute is set as a cell property on the title cell.
this._invalidateCellValue(aNode, this.COLUMN_TYPE_TITLE);
}
}).bind(this)
);
}
},
@ -862,6 +876,32 @@ PlacesTreeView.prototype = {
containerStateChanged:
function PTV_containerStateChanged(aNode, aOldState, aNewState) {
this.invalidateContainer(aNode);
if (PlacesUtils.nodeIsFolder(aNode) ||
(this._flatList && aNode == this._rootNode)) {
let queryOptions = PlacesUtils.asQuery(this._rootNode).queryOptions;
if (queryOptions.excludeItems) {
return;
}
PlacesUtils.livemarks.getLivemark({ id: aNode.itemId },
(function (aStatus, aLivemark) {
if (Components.isSuccessCode(aStatus)) {
let shouldInvalidate = !aNode._feedURI;
aNode._feedURI = aLivemark.feedURI;
if (aNewState == Components.interfaces.nsINavHistoryContainerResultNode.STATE_OPENED) {
aLivemark.registerForUpdates(aNode, this);
aLivemark.reload();
if (shouldInvalidate)
this.invalidateContainer(aNode);
}
else {
aLivemark.unregisterForUpdates(aNode);
}
}
}).bind(this)
);
}
},
invalidateContainer: function PTV_invalidateContainer(aContainer) {
@ -955,6 +995,13 @@ PlacesTreeView.prototype = {
}
}
if (aContainer._feedURI) {
let queryOptions = PlacesUtils.asQuery(this._result.root).queryOptions;
if (!queryOptions.excludeItems) {
this._populateLivemarkContainer(aContainer);
}
}
this._tree.endUpdateBatch();
// Restore selection.
@ -1109,8 +1156,22 @@ PlacesTreeView.prototype = {
}
else if (nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER ||
nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT) {
if (PlacesUtils.nodeIsLivemarkContainer(node))
if (node._feedURI) {
properties.push(this._getAtomFor("livemark"));
}
else {
PlacesUtils.livemarks.getLivemark(
{ id: node.itemId },
(function (aStatus, aLivemark) {
if (Components.isSuccessCode(aStatus)) {
node._feedURI = aLivemark.feedURI;
node._cellProperties.push(this._getAtomFor("livemark"));
// The livemark attribute is set as a cell property on the title cell.
this._invalidateCellValue(node, this.COLUMN_TYPE_TITLE);
}
}).bind(this)
);
}
}
if (itemId != -1) {
@ -1123,9 +1184,12 @@ PlacesTreeView.prototype = {
properties.push(this._getAtomFor("separator"));
else if (PlacesUtils.nodeIsURI(node)) {
properties.push(this._getAtomFor(PlacesUIUtils.guessUrlSchemeForUI(node.uri)));
if (itemId != -1) {
if (PlacesUtils.nodeIsLivemarkContainer(node.parent))
properties.push(this._getAtomFor("livemarkItem"));
if (node.parent._feedURI) {
properties.push(this._getAtomFor("livemarkItem"));
if (node.accessCount) {
properties.push(this._getAtomFor("visited"));
}
}
}
@ -1154,7 +1218,7 @@ PlacesTreeView.prototype = {
let parent = node.parent;
if ((PlacesUtils.nodeIsQuery(parent) ||
PlacesUtils.nodeIsFolder(parent)) &&
!node.hasChildren)
!PlacesUtils.asQuery(node).hasChildren)
return PlacesUtils.asQuery(parent).queryOptions.expandQueries;
}
return true;
@ -1174,8 +1238,14 @@ PlacesTreeView.prototype = {
if (this._flatList)
return true;
let node = this._rows[aRow];
if (node._feedURI) {
let queryOptions = PlacesUtils.asQuery(this._result.root).queryOptions;
return queryOptions.excludeItems;
}
// All containers are listed in the rows array.
return !this._rows[aRow].hasChildren;
return !node.hasChildren;
},
isSeparator: function PTV_isSeparator(aRow) {
@ -1418,15 +1488,18 @@ PlacesTreeView.prototype = {
return;
}
let resource = this._getResourceForNode(node);
if (resource) {
const openLiteral = PlacesUIUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open");
const trueLiteral = PlacesUIUtils.RDF.GetLiteral("true");
// Persist containers open status, but never persist livemarks.
if (!node._feedURI) {
let resource = this._getResourceForNode(node);
if (resource) {
const openLiteral = PlacesUIUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open");
const trueLiteral = PlacesUIUtils.RDF.GetLiteral("true");
if (node.containerOpen)
PlacesUIUtils.localStore.Unassert(resource, openLiteral, trueLiteral);
else
PlacesUIUtils.localStore.Assert(resource, openLiteral, trueLiteral, true);
if (node.containerOpen)
PlacesUIUtils.localStore.Unassert(resource, openLiteral, trueLiteral);
else
PlacesUIUtils.localStore.Assert(resource, openLiteral, trueLiteral, true);
}
}
node.containerOpen = !node.containerOpen;
@ -1569,10 +1642,8 @@ PlacesTreeView.prototype = {
// The following items are never editable:
// * Read-only items.
// * places-roots
// * livemark items
// * separators
if (PlacesUtils.nodeIsReadOnly(node) ||
PlacesUtils.nodeIsLivemarkItem(node) ||
PlacesUtils.nodeIsSeparator(node))
return false;

View File

@ -41,7 +41,7 @@ function test() {
ok(PlacesUIUtils, "checking PlacesUIUtils, running in chrome context?");
/*
- create, a test folder, add bookmark, separator, livemark to it
- create, a test folder, add bookmark, separator to it
- fetch guids for all
- copy the folder
- test that guids are all different
@ -66,10 +66,6 @@ function test() {
PlacesUtils.bookmarks.insertBookmark(folderAId, PlacesUtils._uri("http://foo"),
-1, "test bookmark");
PlacesUtils.bookmarks.insertSeparator(folderAId, -1);
PlacesUtils.livemarks.createLivemarkFolderOnly(folderAId, "test livemark",
PlacesUtils._uri("http://test"),
PlacesUtils._uri("http://test"), -1);
var folderANode = testRootNode.getChild(0);
var folderAGUIDs = getGUIDs(folderANode);
@ -125,8 +121,7 @@ function getGUIDs(aNode) {
var GUIDs = {
folder: PlacesUtils.bookmarks.getItemGUID(aNode.itemId),
bookmark: PlacesUtils.bookmarks.getItemGUID(aNode.getChild(0).itemId),
separator: PlacesUtils.bookmarks.getItemGUID(aNode.getChild(1).itemId),
livemark: PlacesUtils.bookmarks.getItemGUID(aNode.getChild(2).itemId)
separator: PlacesUtils.bookmarks.getItemGUID(aNode.getChild(1).itemId)
};
aNode.containerOpen = false;
return GUIDs;
@ -144,8 +139,7 @@ function checkGUIDs(aFolderNode, aGUIDs, aShouldMatch) {
var allMatch = check(aFolderNode, aGUIDs.folder, aShouldMatch) &&
check(aFolderNode.getChild(0), aGUIDs.bookmark, aShouldMatch) &&
check(aFolderNode.getChild(1), aGUIDs.separator, aShouldMatch) &&
check(aFolderNode.getChild(2), aGUIDs.livemark, aShouldMatch);
check(aFolderNode.getChild(1), aGUIDs.separator, aShouldMatch)
aFolderNode.containerOpen = false;
return allMatch;

View File

@ -95,11 +95,6 @@ function startTest() {
"bmf1");
addedBookmarks.push(id);
bs.moveItem(id, bs.bookmarksMenuFolder, 0);
id = PlacesUtils.livemarks.createLivemarkFolderOnly(
bs.bookmarksMenuFolder, "bml",
PlacesUtils._uri("http://bml.siteuri.mozilla.org/"),
PlacesUtils._uri("http://bml.feeduri.mozilla.org/"), bs.DEFAULT_INDEX);
addedBookmarks.push(id);
// TOOLBAR
ok(true, "*** Acting on toolbar bookmarks");
@ -128,10 +123,6 @@ function startTest() {
"bmf1");
addedBookmarks.push(id);
bs.moveItem(id, bs.toolbarFolder, 0);
id = PlacesUtils.livemarks.createLivemarkFolderOnly(
bs.toolbarFolder, "tbl", PlacesUtils._uri("http://tbl.siteuri.mozilla.org/"),
PlacesUtils._uri("http://tbl.feeduri.mozilla.org/"), bs.DEFAULT_INDEX);
addedBookmarks.push(id);
// UNSORTED
ok(true, "*** Acting on unsorted bookmarks");
@ -160,11 +151,6 @@ function startTest() {
"ubf1");
addedBookmarks.push(id);
bs.moveItem(id, bs.unfiledBookmarksFolder, 0);
id = PlacesUtils.livemarks.createLivemarkFolderOnly(
bs.unfiledBookmarksFolder, "bubl",
PlacesUtils._uri("http://bubl.siteuri.mozilla.org/"),
PlacesUtils._uri("http://bubl.feeduri.mozilla.org/"), bs.DEFAULT_INDEX);
addedBookmarks.push(id);
// Remove all added bookmarks.
addedBookmarks.forEach(function (aItem) {
@ -201,27 +187,7 @@ var bookmarksObserver = {
]),
// nsIAnnotationObserver
onItemAnnotationSet: function(aItemId, aAnnotationName) {
if (aAnnotationName == PlacesUtils.LMANNO_FEEDURI) {
// Check that item is recognized as a livemark.
let validator = function(aTreeRowIndex) {
let tree = gLibrary.PlacesOrganizer._places;
let livemarkAtom = Cc["@mozilla.org/atom-service;1"].
getService(Ci.nsIAtomService).
getAtom("livemark");
let properties = Cc["@mozilla.org/supports-array;1"].
createInstance(Ci.nsISupportsArray);
tree.view.getCellProperties(aTreeRowIndex,
tree.columns.getColumnAt(0),
properties);
return properties.GetIndexOf(livemarkAtom) != -1;
};
var [node, index, valid] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places, validator);
isnot(node, null, "Found new Places node in left pane at " + index);
ok(valid, "Node is recognized as a livemark");
}
},
onItemAnnotationSet: function() {},
onItemAnnotationRemoved: function() {},
onPageAnnotationSet: function() {},
onPageAnnotationRemoved: function() {},

View File

@ -118,11 +118,6 @@ function startTest() {
bs.setItemTitle(id, "bmf1_edited");
addedBookmarks.push(id);
bs.moveItem(id, bs.bookmarksMenuFolder, 0);
id = PlacesUtils.livemarks.createLivemarkFolderOnly(
bs.bookmarksMenuFolder, "bml",
PlacesUtils._uri("http://bml.siteuri.mozilla.org/"),
PlacesUtils._uri("http://bml.feeduri.mozilla.org/"), bs.DEFAULT_INDEX);
addedBookmarks.push(id);
// TOOLBAR
info("*** Acting on toolbar bookmarks");
@ -154,10 +149,6 @@ function startTest() {
bs.setItemTitle(id, "tbf1_edited");
addedBookmarks.push(id);
bs.moveItem(id, bs.toolbarFolder, 0);
id = PlacesUtils.livemarks.createLivemarkFolderOnly(
bs.toolbarFolder, "tbl", PlacesUtils._uri("http://tbl.siteuri.mozilla.org/"),
PlacesUtils._uri("http://tbl.feeduri.mozilla.org/"), bs.DEFAULT_INDEX);
addedBookmarks.push(id);
// UNSORTED
info("*** Acting on unsorted bookmarks");
@ -187,11 +178,6 @@ function startTest() {
bs.setItemTitle(id, "bubf1_edited");
addedBookmarks.push(id);
bs.moveItem(id, bs.unfiledBookmarksFolder, 0);
id = PlacesUtils.livemarks.createLivemarkFolderOnly(
bs.unfiledBookmarksFolder, "bubl",
PlacesUtils._uri("http://bubl.siteuri.mozilla.org/"),
PlacesUtils._uri("http://bubl.feeduri.mozilla.org/"), bs.DEFAULT_INDEX);
addedBookmarks.push(id);
// Remove all added bookmarks.
addedBookmarks.forEach(function (aItem) {
@ -233,38 +219,7 @@ var bookmarksObserver = {
]),
// nsIAnnotationObserver
onItemAnnotationSet: function(aItemId, aAnnotationName) {
if (aAnnotationName == PlacesUtils.LMANNO_FEEDURI) {
var views = getViewsForFolder(PlacesUtils.bookmarks.getFolderIdForItem(aItemId));
ok(views.length > 0, "Found affected views (" + views.length + "): " + views);
// Check that item is recognized as a livemark.
let validator = function(aElementOrTreeIndex) {
if (typeof(aElementOrTreeIndex) == "number") {
var sidebar = document.getElementById("sidebar");
var tree = sidebar.contentDocument.getElementById("bookmarks-view");
let livemarkAtom = Cc["@mozilla.org/atom-service;1"].
getService(Ci.nsIAtomService).
getAtom("livemark");
let properties = Cc["@mozilla.org/supports-array;1"].
createInstance(Ci.nsISupportsArray);
tree.view.getCellProperties(aElementOrTreeIndex,
tree.columns.getColumnAt(0),
properties);
return properties.GetIndexOf(livemarkAtom) != -1;
}
else {
return aElementOrTreeIndex.hasAttribute("livemark");
}
};
for (var i = 0; i < views.length; i++) {
var [node, index, valid] = searchItemInView(aItemId, views[i], validator);
isnot(node, null, "Found new Places node in " + views[i] + " at " + index);
ok(valid, "Node is recognized as a livemark");
}
}
},
onItemAnnotationSet: function() {},
onItemAnnotationRemoved: function() {},
onPageAnnotationSet: function() {},
onPageAnnotationRemoved: function() {},

View File

@ -102,7 +102,7 @@ let (backup_date = new Date().toLocaleFormat("%Y-%m-%d")) {
}
// Smart bookmarks constants.
const SMART_BOOKMARKS_VERSION = 2;
const SMART_BOOKMARKS_VERSION = 3;
const SMART_BOOKMARKS_ON_TOOLBAR = 1;
const SMART_BOOKMARKS_ON_MENU = 3; // Takes in count the additional separator.

View File

@ -36,11 +36,6 @@
*
* ***** END LICENSE BLOCK ***** */
// The following components need to be initialized to perform tests without
// asserting in debug builds (Bug 448804).
Cc["@mozilla.org/browser/livemark-service;2"].getService(Ci.nsILivemarkService);
Cc["@mozilla.org/feed-processor;1"].createInstance(Ci.nsIFeedProcessor);
const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
const DESCRIPTION_ANNO = "bookmarkProperties/description";
const POST_DATA_ANNO = "bookmarkProperties/POSTData";
@ -49,6 +44,7 @@ do_check_eq(typeof PlacesUtils, "object");
// main
function run_test() {
do_test_pending();
/*
HTML+FEATURES SUMMARY:
- import legacy bookmarks
@ -92,21 +88,25 @@ function run_test() {
populate();
validate();
// Test exporting a Places canonical json file.
// 1. export to bookmarks.exported.json
// 2. empty bookmarks db
// 3. import bookmarks.exported.json
// 4. run the test-suite
try {
PlacesUtils.backups.saveBookmarksToJSONFile(jsonFile);
} catch(ex) { do_throw("couldn't export to file: " + ex); }
LOG("exported json");
try {
PlacesUtils.restoreBookmarksFromJSONFile(jsonFile);
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
LOG("imported json");
validate();
LOG("validated import");
waitForAsyncUpdates(function () {
// Test exporting a Places canonical json file.
// 1. export to bookmarks.exported.json
// 2. empty bookmarks db
// 3. import bookmarks.exported.json
// 4. run the test-suite
try {
PlacesUtils.backups.saveBookmarksToJSONFile(jsonFile);
} catch(ex) { do_throw("couldn't export to file: " + ex); }
LOG("exported json");
try {
PlacesUtils.restoreBookmarksFromJSONFile(jsonFile);
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
LOG("imported json");
validate();
LOG("validated import");
waitForAsyncUpdates(do_test_finished);
});
}
var tagData = [
@ -243,14 +243,17 @@ function testToolbarFolder() {
var livemark = toolbar.getChild(1);
// title
do_check_eq("Latest Headlines", livemark.title);
// livemark check
do_check_true(PlacesUtils.livemarks.isLivemark(livemark.itemId));
// site url
do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
PlacesUtils.livemarks.getSiteURI(livemark.itemId).spec);
// feed url
do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
PlacesUtils.livemarks.getFeedURI(livemark.itemId).spec);
PlacesUtils.livemarks.getLivemark(
{ id: livemark.itemId },
function (aStatus, aLivemark) {
do_check_true(Components.isSuccessCode(aStatus));
do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
aLivemark.siteURI.spec);
do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
aLivemark.feedURI.spec);
}
);
// test added bookmark data
var child = toolbar.getChild(2);

View File

@ -49,8 +49,6 @@ var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
var as = Cc["@mozilla.org/browser/annotation-service;1"].
getService(Ci.nsIAnnotationService);
var lms = Cc["@mozilla.org/browser/livemark-service;2"].
getService(Ci.nsILivemarkService);
var icos = Cc["@mozilla.org/browser/favicon-service;1"].
getService(Ci.nsIFaviconService);
var ps = Cc["@mozilla.org/preferences-service;1"].
@ -65,8 +63,9 @@ const POST_DATA_ANNO = "bookmarkProperties/POSTData";
const TEST_FAVICON_PAGE_URL = "http://en-US.www.mozilla.com/en-US/firefox/central/";
const TEST_FAVICON_DATA_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==";
// main
function run_test() {
do_test_pending();
// avoid creating the places smart folder during tests
ps.setIntPref("browser.places.smartBookmarksVersion", -1);
@ -79,38 +78,41 @@ function run_test() {
// Check that every bookmark is correct
// Corrupt bookmarks should not have been imported
database_check();
waitForAsyncUpdates(function() {
// Create corruption in database
var corruptItemId = bs.insertBookmark(bs.toolbarFolder,
uri("http://test.mozilla.org"),
bs.DEFAULT_INDEX, "We love belugas");
var stmt = dbConn.createStatement("UPDATE moz_bookmarks SET fk = NULL WHERE id = :itemId");
stmt.params.itemId = corruptItemId;
stmt.execute();
stmt.finalize();
// Create corruption in database
var corruptItemId = bs.insertBookmark(bs.toolbarFolder,
uri("http://test.mozilla.org"),
bs.DEFAULT_INDEX, "We love belugas");
var stmt = dbConn.createStatement("UPDATE moz_bookmarks SET fk = NULL WHERE id = :itemId");
stmt.params.itemId = corruptItemId;
stmt.execute();
stmt.finalize();
// Export bookmarks
var bookmarksFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
bookmarksFile.append("bookmarks.exported.html");
if (bookmarksFile.exists())
bookmarksFile.remove(false);
bookmarksFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, 0600);
if (!bookmarksFile.exists())
do_throw("couldn't create file: bookmarks.exported.html");
try {
ies.exportHTMLToFile(bookmarksFile);
} catch(ex) { do_throw("couldn't export to bookmarks.exported.html: " + ex); }
// Export bookmarks
var bookmarksFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
bookmarksFile.append("bookmarks.exported.html");
if (bookmarksFile.exists())
bookmarksFile.remove(false);
bookmarksFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, 0600);
if (!bookmarksFile.exists())
do_throw("couldn't create file: bookmarks.exported.html");
try {
ies.exportHTMLToFile(bookmarksFile);
} catch(ex) { do_throw("couldn't export to bookmarks.exported.html: " + ex); }
// Clear all bookmarks
remove_all_bookmarks();
// Clear all bookmarks
remove_all_bookmarks();
// Import bookmarks
try {
ies.importHTMLFromFile(bookmarksFile, true);
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
// Import bookmarks
try {
ies.importHTMLFromFile(bookmarksFile, true);
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
// Check that every bookmark is correct
database_check();
// Check that every bookmark is correct
database_check();
waitForAsyncUpdates(do_test_finished);
});
}
/*
@ -192,14 +194,16 @@ function database_check() {
var livemark = toolbar.getChild(1);
// title
do_check_eq("Latest Headlines", livemark.title);
// livemark check
do_check_true(lms.isLivemark(livemark.itemId));
// site url
do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
lms.getSiteURI(livemark.itemId).spec);
// feed url
do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
lms.getFeedURI(livemark.itemId).spec);
PlacesUtils.livemarks.getLivemark(
{ id: livemark.itemId },
function (aStatus, aLivemark) {
do_check_true(Components.isSuccessCode(aStatus));
do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
aLivemark.siteURI.spec);
do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
aLivemark.feedURI.spec);
}
);
// cleanup
toolbar.containerOpen = false;

View File

@ -83,7 +83,6 @@ let test_bookmarks = {
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
},
{ title: "Latest Headlines",
description: "Livemark test comment",
url: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
feedUrl: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
}
@ -105,6 +104,10 @@ let importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
function run_test()
{
run_next_test();
}
add_test(function setup() {
// Avoid creating smart bookmarks during the test.
Services.prefs.setIntPref("browser.places.smartBookmarksVersion", -1);
@ -131,16 +134,20 @@ function run_test()
importer.importHTMLFromFile(gBookmarksFileOld, true);
} catch(ex) { do_throw("couldn't import legacy bookmarks file: " + ex); }
testImportedBookmarks();
waitForAsyncUpdates(function () {
testImportedBookmarks();
// Prepare for next tests.
try {
importer.exportHTMLToFile(gBookmarksFileNew);
} catch(ex) { do_throw("couldn't export to file: " + ex); }
// Prepare for next tests.
try {
importer.exportHTMLToFile(gBookmarksFileNew);
} catch(ex) { do_throw("couldn't export to file: " + ex); }
remove_all_bookmarks();
run_next_test();
}
waitForAsyncUpdates(function () {
remove_all_bookmarks();
run_next_test();
});
});
});
add_test(function test_import_new()
{
@ -152,10 +159,14 @@ add_test(function test_import_new()
importer.importHTMLFromFile(gBookmarksFileNew, true);
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
testImportedBookmarks();
waitForAsyncUpdates(function () {
testImportedBookmarks();
remove_all_bookmarks();
run_next_test();
waitForAsyncUpdates(function () {
remove_all_bookmarks();
run_next_test();
});
});
});
add_test(function test_emptytitle_export()
@ -189,18 +200,22 @@ add_test(function test_emptytitle_export()
importer.importHTMLFromFile(gBookmarksFileNew, true);
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
testImportedBookmarks();
waitForAsyncUpdates(function () {
testImportedBookmarks();
// Cleanup.
test_bookmarks.unfiled.pop();
PlacesUtils.bookmarks.removeItem(id);
// Cleanup.
test_bookmarks.unfiled.pop();
PlacesUtils.bookmarks.removeItem(id);
try {
importer.exportHTMLToFile(gBookmarksFileNew);
} catch(ex) { do_throw("couldn't export to file: " + ex); }
try {
importer.exportHTMLToFile(gBookmarksFileNew);
} catch(ex) { do_throw("couldn't export to file: " + ex); }
remove_all_bookmarks();
run_next_test();
waitForAsyncUpdates(function () {
remove_all_bookmarks();
run_next_test();
});
});
});
add_test(function test_import_preplaces_to_folder()
@ -218,11 +233,15 @@ add_test(function test_import_preplaces_to_folder()
importer.importHTMLFromFileToFolder(gBookmarksFileOld, testFolder, false);
} catch(ex) { do_throw("couldn't import the exported file to folder: " + ex); }
// Import-to-folder creates subfolders for toolbar and unfiled.
testImportedBookmarksToFolder(testFolder);
waitForAsyncUpdates(function () {
// Import-to-folder creates subfolders for toolbar and unfiled.
testImportedBookmarksToFolder(testFolder);
remove_all_bookmarks();
run_next_test();
waitForAsyncUpdates(function () {
remove_all_bookmarks();
run_next_test();
});
});
});
add_test(function test_import_to_folder()
@ -240,11 +259,15 @@ add_test(function test_import_to_folder()
importer.importHTMLFromFileToFolder(gBookmarksFileNew, testFolder, false);
} catch(ex) { do_throw("couldn't import the exported file to folder: " + ex); }
// Import-to-folder creates subfolders for toolbar and unfiled.
testImportedBookmarksToFolder(testFolder);
waitForAsyncUpdates(function () {
// Import-to-folder creates subfolders for toolbar and unfiled.
testImportedBookmarksToFolder(testFolder);
remove_all_bookmarks();
run_next_test();
waitForAsyncUpdates(function () {
remove_all_bookmarks();
run_next_test();
});
});
});
add_test(function test_import_ontop()
@ -267,10 +290,14 @@ add_test(function test_import_ontop()
importer.importHTMLFromFile(gBookmarksFileNew, true);
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
testImportedBookmarks();
waitForAsyncUpdates(function () {
testImportedBookmarks();
remove_all_bookmarks();
run_next_test();
waitForAsyncUpdates(function () {
remove_all_bookmarks();
run_next_test();
});
});
});
function testImportedBookmarks()
@ -350,8 +377,14 @@ function checkItem(aExpected, aNode)
aExpected.lastModified);
break;
case "url":
if (!PlacesUtils.livemarks.isLivemark(id))
do_check_eq(aNode.uri, aExpected.url);
PlacesUtils.livemarks.getLivemark(
{ id: id },
function (aStatus, aLivemark) {
if (!Components.isSuccessCode(aStatus)) {
do_check_eq(aNode.uri, aExpected.url);
}
}
);
break;
case "icon":
let faviconURI = PlacesUtils.favicons.getFaviconForPage(
@ -378,11 +411,14 @@ function checkItem(aExpected, aNode)
aExpected.charset);
break;
case "feedUrl":
do_check_true(PlacesUtils.livemarks.isLivemark(id));
do_check_eq(PlacesUtils.livemarks.getSiteURI(id).spec,
aExpected.url);
do_check_eq(PlacesUtils.livemarks.getFeedURI(id).spec,
aExpected.feedUrl);
PlacesUtils.livemarks.getLivemark(
{ id: id },
function (aStatus, aLivemark) {
do_check_true(Components.isSuccessCode(aStatus));
do_check_eq(aLivemark.siteURI.spec, aExpected.url);
do_check_eq(aLivemark.feedURI.spec, Expected.feedUrl);
}
);
break;
case "children":
let folder = aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);

View File

@ -39,7 +39,6 @@
* ***** END LICENSE BLOCK ***** */
var bmsvc = PlacesUtils.bookmarks;
var lmsvc = PlacesUtils.livemarks;
var ptSvc = PlacesUIUtils.ptm;
var tagssvc = PlacesUtils.tagging;
var annosvc = PlacesUtils.annotations;
@ -419,84 +418,6 @@ function run_test() {
do_check_eq(observer._itemChangedProperty, "keyword");
do_check_eq(observer._itemChangedValue, "");
// Testing create livemark
var txn12 = ptSvc.createLivemark(uri("http://feeduri.com"),
uri("http://siteuri.com"),
"Livemark1", root);
txn12.doTransaction();
var lvmkId = observer._itemAddedId;
do_check_true(lmsvc.isLivemark(lvmkId));
do_check_eq(lmsvc.getSiteURI(lvmkId).spec, "http://siteuri.com/");
do_check_eq(lmsvc.getFeedURI(lvmkId).spec, "http://feeduri.com/");
txn12.undoTransaction();
do_check_false(lmsvc.isLivemark(lvmkId));
txn12.redoTransaction();
lvmkId = observer._itemAddedId;
do_check_true(lmsvc.isLivemark(lvmkId));
do_check_eq(lmsvc.getSiteURI(lvmkId).spec, "http://siteuri.com/");
do_check_eq(lmsvc.getFeedURI(lvmkId).spec, "http://feeduri.com/");
// editLivemarkSiteURI
var txn13 = ptSvc.editLivemarkSiteURI(lvmkId, uri("http://new-siteuri.com/"));
txn13.doTransaction();
do_check_eq(observer._itemChangedId, lvmkId);
do_check_eq(observer._itemChangedProperty, "livemark/siteURI");
do_check_eq(lmsvc.getSiteURI(lvmkId).spec, "http://new-siteuri.com/");
txn13.undoTransaction();
do_check_eq(observer._itemChangedId, lvmkId);
do_check_eq(observer._itemChangedProperty, "livemark/siteURI");
do_check_eq(observer._itemChangedValue, "");
do_check_eq(lmsvc.getSiteURI(lvmkId).spec, "http://siteuri.com/");
txn13.redoTransaction();
do_check_eq(observer._itemChangedId, lvmkId);
do_check_eq(observer._itemChangedProperty, "livemark/siteURI");
do_check_eq(lmsvc.getSiteURI(lvmkId).spec, "http://new-siteuri.com/");
txn13.undoTransaction();
do_check_eq(observer._itemChangedId, lvmkId);
do_check_eq(observer._itemChangedProperty, "livemark/siteURI");
do_check_eq(observer._itemChangedValue, "");
do_check_eq(lmsvc.getSiteURI(lvmkId).spec, "http://siteuri.com/");
// editLivemarkFeedURI
var txn14 = ptSvc.editLivemarkFeedURI(lvmkId, uri("http://new-feeduri.com/"));
txn14.doTransaction();
do_check_eq(observer._itemChangedId, lvmkId);
do_check_eq(observer._itemChangedProperty, "livemark/feedURI");
do_check_eq(lmsvc.getFeedURI(lvmkId).spec, "http://new-feeduri.com/");
txn14.undoTransaction();
do_check_eq(observer._itemChangedId, lvmkId);
do_check_eq(observer._itemChangedProperty, "livemark/feedURI");
do_check_eq(observer._itemChangedValue, "");
do_check_eq(lmsvc.getFeedURI(lvmkId).spec, "http://feeduri.com/");
txn14.redoTransaction();
do_check_eq(observer._itemChangedId, lvmkId);
do_check_eq(observer._itemChangedProperty, "livemark/feedURI");
do_check_eq(observer._itemChangedValue, "");
do_check_eq(lmsvc.getFeedURI(lvmkId).spec, "http://new-feeduri.com/");
txn14.undoTransaction();
do_check_eq(observer._itemChangedId, lvmkId);
do_check_eq(observer._itemChangedProperty, "livemark/feedURI");
do_check_eq(observer._itemChangedValue, "");
do_check_eq(lmsvc.getFeedURI(lvmkId).spec, "http://feeduri.com/");
// Testing remove livemark
// Set an annotation and check that we don't lose it on undo
annosvc.setItemAnnotation(lvmkId, "livemark/testAnno", "testAnno",
0, annosvc.EXPIRE_NEVER);
var txn15 = ptSvc.removeItem(lvmkId);
txn15.doTransaction();
do_check_false(lmsvc.isLivemark(lvmkId));
do_check_eq(observer._itemRemovedId, lvmkId);
txn15.undoTransaction();
lvmkId = observer._itemAddedId;
do_check_true(lmsvc.isLivemark(lvmkId));
do_check_eq(lmsvc.getSiteURI(lvmkId).spec, "http://siteuri.com/");
do_check_eq(lmsvc.getFeedURI(lvmkId).spec, "http://feeduri.com/");
do_check_eq(annosvc.getItemAnnotation(lvmkId, "livemark/testAnno"), "testAnno");
txn15.redoTransaction();
do_check_false(lmsvc.isLivemark(lvmkId));
do_check_eq(observer._itemRemovedId, lvmkId);
// Test LoadInSidebar transaction.
var txn16 = ptSvc.setLoadInSidebar(bkmk1Id, true);
txn16.doTransaction();

View File

@ -41,47 +41,65 @@
* This test will ensure any transactions service that is going to create
* a new item, won't replace the GUID when undoing and redoing the action.
*/
var bmsvc = PlacesUtils.bookmarks;
var txnsvc = PlacesUIUtils.ptm;
function test_GUID_persistance(aTxn) {
aTxn.doTransaction();
var itemId = bmsvc.getIdForItemAt(bmsvc.unfiledBookmarksFolder, 0);
var GUID = bmsvc.getItemGUID(itemId);
aTxn.undoTransaction();
aTxn.redoTransaction();
do_check_eq(GUID, bmsvc.getItemGUID(itemId));
aTxn.undoTransaction();
waitForAsyncUpdates(function () {
let itemId = PlacesUtils.bookmarks
.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
let GUID = PlacesUtils.bookmarks.getItemGUID(itemId);
aTxn.undoTransaction();
aTxn.redoTransaction();
waitForAsyncUpdates(function() {
let itemId = PlacesUtils.bookmarks
.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
do_check_eq(GUID, PlacesUtils.bookmarks.getItemGUID(itemId));
aTxn.undoTransaction();
waitForAsyncUpdates(run_next_test);
});
});
}
function run_test() {
// Create folder.
var createFolderTxn = txnsvc.createFolder("Test folder",
bmsvc.unfiledBookmarksFolder,
bmsvc.DEFAULT_INDEX);
test_GUID_persistance(createFolderTxn);
// Create bookmark.
var createBookmarkTxn = txnsvc.createItem(uri("http://www.example.com"),
bmsvc.unfiledBookmarksFolder,
bmsvc.DEFAULT_INDEX,
"Test bookmark");
test_GUID_persistance(createBookmarkTxn);
// Create separator.
var createSeparatorTxn = txnsvc.createSeparator(bmsvc.unfiledBookmarksFolder,
bmsvc.DEFAULT_INDEX);
test_GUID_persistance(createFolderTxn);
// Create livemark.
var createLivemarkTxn = txnsvc.createLivemark(uri("http://feeduri.com"),
uri("http://siteuri.com"),
"Test livemark",
bmsvc.unfiledBookmarksFolder,
bmsvc.DEFAULT_INDEX);
test_GUID_persistance(createLivemarkTxn);
// Tag URI.
var tagURITxn = txnsvc.tagURI(uri("http://www.example.com"), ["foo"]);
test_GUID_persistance(tagURITxn);
run_next_test();
}
add_test(function create_folder() {
let createFolderTxn = new PlacesCreateFolderTransaction(
"Test folder", PlacesUtils.unfiledBookmarksFolderId,
PlacesUtils.bookmarks.DEFAULT_INDEX
);
test_GUID_persistance(createFolderTxn);
});
add_test(function create_bookmark() {
let createBookmarkTxn = new PlacesCreateBookmarkTransaction(
NetUtil.newURI("http://www.example.com"), PlacesUtils.unfiledBookmarksFolderId,
PlacesUtils.bookmarks.DEFAULT_INDEX, "Test bookmark"
);
test_GUID_persistance(createBookmarkTxn);
});
add_test(function create_separator() {
let createSeparatorTxn = new PlacesCreateSeparatorTransaction(
PlacesUtils.unfiledBookmarksFolderId, PlacesUtils.bookmarks.DEFAULT_INDEX
);
test_GUID_persistance(createSeparatorTxn);
});
add_test(function tag_uri() {
let tagURITxn = new PlacesTagURITransaction(
NetUtil.newURI("http://www.example.com"), ["foo"]
);
test_GUID_persistance(tagURITxn);
});
add_test(function create_livemark() {
let createLivemarkTxn = new PlacesCreateLivemarkTransaction(
NetUtil.newURI("http://feeduri.com"), NetUtil.newURI("http://siteuri.com"),
"Test livemark", PlacesUtils.unfiledBookmarksFolderId,
PlacesUtils.bookmarks.DEFAULT_INDEX
);
test_GUID_persistance(createLivemarkTxn);
});

View File

@ -55,7 +55,8 @@ var Utilities = {
get livemarks() {
let livemarks = Cc["@mozilla.org/browser/livemark-service;2"].
getService(Ci.nsILivemarkService);
getService[Ci.mozIAsyncLivemarks].
QueryInterface(Ci.nsILivemarkService);
this.__defineGetter__("livemarks", function() livemarks);
return this.livemarks;
},

View File

@ -213,6 +213,11 @@ menuitem.bookmark-item {
.bookmark-item[container][livemark] .bookmark-item {
list-style-image: url("chrome://browser/skin/places/livemark-item.png");
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
.bookmark-item[container][livemark] .bookmark-item[visited] {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
.bookmark-item[container][query] {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 732 B

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -28,6 +28,11 @@ treechildren::-moz-tree-image(title) {
treechildren::-moz-tree-image(title, livemarkItem) {
list-style-image: url("chrome://browser/skin/places/livemark-item.png");
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
treechildren::-moz-tree-image(title, livemarkItem, visited) {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
treechildren::-moz-tree-image(title, separator) {

View File

@ -258,7 +258,12 @@ toolbarbutton.bookmark-item > menupopup {
}
.bookmark-item[livemark] .menuitem-iconic {
list-style-image: url("chrome://browser/skin/livemark-item.png");
list-style-image: url("chrome://browser/skin/places/livemark-item.png");
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
.bookmark-item[livemark] .menuitem-iconic[visited] {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
.bookmark-item menuitem[openInTabs],

View File

@ -29,7 +29,6 @@ browser.jar:
skin/classic/browser/menu-back.png
skin/classic/browser/menu-forward.png
skin/classic/browser/page-livemarks.png
skin/classic/browser/livemark-item.png
skin/classic/browser/pageInfo.css
skin/classic/browser/Privacy-16.png
skin/classic/browser/Privacy-48.png
@ -90,6 +89,7 @@ browser.jar:
skin/classic/browser/places/expander-closed.png (places/expander-closed.png)
skin/classic/browser/places/expander-open-active.png (places/expander-open-active.png)
skin/classic/browser/places/expander-open.png (places/expander-open.png)
skin/classic/browser/places/livemark-item.png (places/livemark-item.png)
skin/classic/browser/preferences/alwaysAsk.png (preferences/alwaysAsk.png)
skin/classic/browser/preferences/application.png (preferences/application.png)
skin/classic/browser/preferences/Options.png (preferences/Options.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -97,7 +97,12 @@ treechildren::-moz-tree-image(title) {
}
treechildren::-moz-tree-image(title, livemarkItem) {
list-style-image: url("chrome://browser/skin/livemark-item.png");
list-style-image: url("chrome://browser/skin/places/livemark-item.png");
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
treechildren::-moz-tree-image(title, livemarkItem, visited) {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
treechildren::-moz-tree-image(title, container),

View File

@ -609,8 +609,12 @@ menuitem.bookmark-item {
}
.bookmark-item[container][livemark] .bookmark-item {
list-style-image: url("chrome://browser/skin/livemark-item.png");
-moz-image-region: auto;
list-style-image: url("chrome://browser/skin/places/livemark-item.png");
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
.bookmark-item[container][livemark] .bookmark-item[visited] {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
.bookmark-item[container][query] {

View File

@ -27,7 +27,6 @@ browser.jar:
skin/classic/browser/pageInfo.css
skin/classic/browser/pageInfo.png (pageInfo.png)
skin/classic/browser/page-livemarks.png (feeds/feedIcon16.png)
skin/classic/browser/livemark-item.png (livemark-item.png)
skin/classic/browser/livemark-folder.png (livemark-folder.png)
skin/classic/browser/Privacy-16.png
skin/classic/browser/Privacy-48.png
@ -80,6 +79,7 @@ browser.jar:
skin/classic/browser/places/allBookmarks.png (places/allBookmarks.png)
skin/classic/browser/places/unsortedBookmarks.png (places/unsortedBookmarks.png)
skin/classic/browser/places/downloads.png (places/downloads.png)
skin/classic/browser/places/livemark-item.png (places/livemark-item.png)
skin/classic/browser/preferences/alwaysAsk.png (preferences/alwaysAsk.png)
skin/classic/browser/preferences/application.png (preferences/application.png)
skin/classic/browser/preferences/mail.png (preferences/mail.png)
@ -196,7 +196,6 @@ browser.jar:
skin/classic/aero/browser/pageInfo.css
skin/classic/aero/browser/pageInfo.png (pageInfo-aero.png)
skin/classic/aero/browser/page-livemarks.png (feeds/feedIcon16-aero.png)
skin/classic/aero/browser/livemark-item.png (livemark-item-aero.png)
skin/classic/aero/browser/livemark-folder.png (livemark-folder-aero.png)
skin/classic/aero/browser/Privacy-16.png (Privacy-16-aero.png)
skin/classic/aero/browser/Privacy-48.png (Privacy-48-aero.png)
@ -249,6 +248,7 @@ browser.jar:
skin/classic/aero/browser/places/allBookmarks.png (places/allBookmarks-aero.png)
skin/classic/aero/browser/places/unsortedBookmarks.png (places/unsortedBookmarks-aero.png)
skin/classic/aero/browser/places/downloads.png (places/downloads.png)
skin/classic/aero/browser/places/livemark-item.png (places/livemark-item.png)
skin/classic/aero/browser/preferences/alwaysAsk.png (preferences/alwaysAsk-aero.png)
skin/classic/aero/browser/preferences/application.png (preferences/application-aero.png)
skin/classic/aero/browser/preferences/mail.png (preferences/mail-aero.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -30,7 +30,12 @@ treechildren::-moz-tree-image(title) {
}
treechildren::-moz-tree-image(title, livemarkItem) {
list-style-image: url("chrome://browser/skin/livemark-item.png");
list-style-image: url("chrome://browser/skin/places/livemark-item.png");
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
treechildren::-moz-tree-image(title, livemarkItem, visited) {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
treechildren::-moz-tree-image(title, separator) {

View File

@ -4,7 +4,7 @@
# a reproducible build is to run it in a know absolute directory.
# We use a directory in /builds/slave because the mozilla infrastructure
# cleans it up automatically.
base_dir = "/builds/slave/moz-toolschain"
base_dir = "/builds/slave/moz-toolchain"
source_dir = base_dir + "/src"
build_dir = base_dir + "/build"
@ -58,6 +58,10 @@ def build_aux_tools(base_dir):
make_build_dir = base_dir + '/make_build'
build_package(make_source_dir, make_build_dir,
["--prefix=%s" % aux_inst_dir], "make")
run_in(unifdef_source_dir, ["make"])
run_in(unifdef_source_dir, ["make", "prefix=%s" % aux_inst_dir, "install"])
tar_build_dir = base_dir + '/tar_build'
build_package(tar_source_dir, tar_build_dir,
["--prefix=%s" % aux_inst_dir])
@ -84,12 +88,17 @@ def build_glibc_aux(stage_dir, inst_dir):
"--libdir=%s/lib64" % inst_dir,
"--prefix=%s" % inst_dir])
def build_linux_headers(inst_dir):
def build_linux_headers_aux(inst_dir):
run_in(linux_source_dir, [old_make, "headers_check"])
run_in(linux_source_dir, [old_make, "INSTALL_HDR_PATH=dest",
"headers_install"])
shutil.move(linux_source_dir + "/dest", inst_dir)
def build_linux_headers(inst_dir):
def f():
build_linux_headers_aux(inst_dir)
with_env({"PATH" : aux_inst_dir + "/bin:%s" % os.environ["PATH"]}, f)
def build_one_stage(env, stage_dir, is_stage_one):
def f():
build_one_stage_aux(stage_dir, is_stage_one)
@ -167,6 +176,7 @@ gcc_version = "4.5.2"
mpfr_version = "2.4.2"
gmp_version = "5.0.1"
mpc_version = "0.8.1"
unifdef_version = "2.6"
binutils_source_uri = "http://ftp.gnu.org/gnu/binutils/binutils-%sa.tar.bz2" % \
binutils_version
@ -178,6 +188,8 @@ tar_source_uri = "http://ftp.gnu.org/gnu/tar/tar-%s.tar.bz2" % \
tar_version
make_source_uri = "http://ftp.gnu.org/gnu/make/make-%s.tar.bz2" % \
make_version
unifdef_source_uri = "http://dotat.at/prog/unifdef/unifdef-%s.tar.gz" % \
unifdef_version
gcc_source_uri = "http://ftp.gnu.org/gnu/gcc/gcc-%s/gcc-%s.tar.bz2" % \
(gcc_version, gcc_version)
mpfr_source_uri = "http://www.mpfr.org/mpfr-%s/mpfr-%s.tar.bz2" % \
@ -191,6 +203,7 @@ glibc_source_tar = download_uri(glibc_source_uri)
linux_source_tar = download_uri(linux_source_uri)
tar_source_tar = download_uri(tar_source_uri)
make_source_tar = download_uri(make_source_uri)
unifdef_source_tar = download_uri(unifdef_source_uri)
mpc_source_tar = download_uri(mpc_source_uri)
mpfr_source_tar = download_uri(mpfr_source_uri)
gmp_source_tar = download_uri(gmp_source_uri)
@ -201,6 +214,7 @@ glibc_source_dir = build_source_dir('glibc-', glibc_version)
linux_source_dir = build_source_dir('linux-', linux_version)
tar_source_dir = build_source_dir('tar-', tar_version)
make_source_dir = build_source_dir('make-', make_version)
unifdef_source_dir = build_source_dir('unifdef-', unifdef_version)
mpc_source_dir = build_source_dir('mpc-', mpc_version)
mpfr_source_dir = build_source_dir('mpfr-', mpfr_version)
gmp_source_dir = build_source_dir('gmp-', gmp_version)
@ -216,6 +230,7 @@ if not os.path.exists(source_dir):
run_in(glibc_source_dir, ["autoconf"])
extract(tar_source_tar, source_dir)
extract(make_source_tar, source_dir)
extract(unifdef_source_tar, source_dir)
extract(mpc_source_tar, source_dir)
extract(mpfr_source_tar, source_dir)
extract(gmp_source_tar, source_dir)

View File

@ -903,13 +903,6 @@ nsEventSource::SetupHttpChannel()
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsIInterfaceRequestor> notificationCallbacks;
mHttpChannel->GetNotificationCallbacks(getter_AddRefs(notificationCallbacks));
if (notificationCallbacks != this) {
mNotificationCallbacks = notificationCallbacks;
mHttpChannel->SetNotificationCallbacks(this);
}
return NS_OK;
}
@ -952,6 +945,13 @@ nsEventSource::InitChannelAndRequestEventSource()
rv = SetupHttpChannel();
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIInterfaceRequestor> notificationCallbacks;
mHttpChannel->GetNotificationCallbacks(getter_AddRefs(notificationCallbacks));
if (notificationCallbacks != this) {
mNotificationCallbacks = notificationCallbacks;
mHttpChannel->SetNotificationCallbacks(this);
}
nsCOMPtr<nsIStreamListener> listener =
new nsCORSListenerProxy(this, mPrincipal, mHttpChannel,
mWithCredentials, &rv);

View File

@ -486,8 +486,13 @@ _TEST_FILES2 = \
test_blobbuilder.html \
fileutils.js \
test_bug338583.html \
test_EventSource_redirects.html \
eventsource.resource \
eventsource.resource^headers^ \
eventsource_redirect.resource \
eventsource_redirect.resource^headers^ \
eventsource_redirect_to.resource \
eventsource_redirect_to.resource^headers^ \
badContentType.eventsource \
badContentType.eventsource^headers^ \
badEventFieldName.eventsource \

View File

@ -0,0 +1,2 @@
redirected

View File

@ -0,0 +1,3 @@
HTTP 301 Moved Permanently
Location: eventsource_redirect_to.resource

View File

@ -0,0 +1,3 @@
retry:500
data: 1

View File

@ -0,0 +1,3 @@
Content-Type: text/event-stream
Cache-Control: no-cache, must-revalidate

View File

@ -0,0 +1,59 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=716841
-->
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
<title>Test for Bug 338583</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body bgColor=white>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=716841">Mozilla Bug 716841</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
function doTest(test_id) {
oldPrefVal = SpecialPowers.getBoolPref("dom.server-events.enabled");
SpecialPowers.setBoolPref("dom.server-events.enabled", true);
ok(true, "here we go");
source = new EventSource("eventsource_redirect.resource");
ok(source.url == "http://mochi.test:8888/tests/content/base/test/eventsource_redirect.resource", "Test failed.");
ok(source.readyState == 0 || source.readyState == 1, "Test failed.");
source.onopen = function (event) {
ok(true, "opened");
};
source.onmessage = function (event) {
ok(true, "event received");
source.close();
SimpleTest.finish();
};
source.onerror = function (event) {
ok(false, "received onError: " + event);
source.close();
SimpleTest.finish();
};
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(doTest);
</script>
</pre>
</body>
</html>

View File

@ -272,7 +272,7 @@ nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, uintN argc, jsval
return CreateImageData(cx, data_width, data_height, NULL, 0, 0, vp);
}
jsdouble width, height;
double width, height;
if (!JS_ValueToNumber(cx, argv[0], &width) ||
!JS_ValueToNumber(cx, argv[1], &height))
return false;
@ -311,7 +311,7 @@ nsIDOMCanvasRenderingContext2D_GetImageData(JSContext *cx, uintN argc, jsval *vp
jsval *argv = JS_ARGV(cx, vp);
jsdouble xd, yd, width, height;
double xd, yd, width, height;
if (!JS_ValueToNumber(cx, argv[0], &xd) ||
!JS_ValueToNumber(cx, argv[1], &yd) ||
!JS_ValueToNumber(cx, argv[2], &width) ||

View File

@ -489,15 +489,9 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
// if we want EGL, try it now
if (!gl && (preferEGL || useANGLE) && !preferOpenGL) {
gl = gl::GLContextProviderEGL::CreateOffscreen(gfxIntSize(width, height), format);
if (gl) {
if (InitAndValidateGL()) {
if (useANGLE) {
gl->SetFlushGuaranteesResolve(true);
}
} else {
LogMessage("Error during ANGLE OpenGL ES initialization");
return NS_ERROR_FAILURE;
}
if (gl && !InitAndValidateGL()) {
LogMessage("Error during ANGLE OpenGL ES initialization");
return NS_ERROR_FAILURE;
}
}
#endif

View File

@ -960,9 +960,6 @@ nsGenericHTMLElement::InsertAdjacentHTML(const nsAString& aPosition,
case eAfterEnd:
destination->InsertBefore(fragment, GetNextSibling(), &rv);
break;
default:
NS_NOTREACHED("Bad position.");
break;
}
return rv;
}

View File

@ -193,41 +193,25 @@ NS_IMPL_STRING_ATTR_WITH_FALLBACK(nsHTMLOptionElement, Label, label, GetText)
NS_IMPL_STRING_ATTR_WITH_FALLBACK(nsHTMLOptionElement, Value, value, GetText)
NS_IMPL_BOOL_ATTR(nsHTMLOptionElement, Disabled, disabled)
NS_IMETHODIMP
NS_IMETHODIMP
nsHTMLOptionElement::GetIndex(PRInt32* aIndex)
{
NS_ENSURE_ARG_POINTER(aIndex);
// When the element is not in a list of options, the index is 0.
*aIndex = 0;
*aIndex = -1; // -1 indicates the index was not found
// Get our containing select content object.
// Only select elements can contain a list of options.
nsHTMLSelectElement* selectElement = GetSelect();
if (selectElement) {
// Get the options from the select object.
nsCOMPtr<nsIDOMHTMLOptionsCollection> options;
selectElement->GetOptions(getter_AddRefs(options));
if (options) {
// Walk the options to find out where we are in the list (ick, O(n))
PRUint32 length = 0;
options->GetLength(&length);
nsCOMPtr<nsIDOMNode> thisOption;
for (PRUint32 i = 0; i < length; i++) {
options->Item(i, getter_AddRefs(thisOption));
if (thisOption.get() == static_cast<nsIDOMNode *>(this)) {
*aIndex = i;
break;
}
}
}
if (!selectElement) {
return NS_OK;
}
return NS_OK;
nsHTMLOptionCollection* options = selectElement->GetOptions();
if (!options) {
return NS_OK;
}
// aIndex will not be set if GetOptionsIndex fails.
return options->GetOptionIndex(this, 0, true, aIndex);
}
bool

View File

@ -1992,6 +1992,8 @@ nsHTMLOptionCollection::GetOptionIndex(mozilla::dom::Element* aOption,
bool aForward,
PRInt32* aIndex)
{
// NOTE: aIndex shouldn't be set if the returned value isn't NS_OK.
PRInt32 index;
// Make the common case fast

View File

@ -143,7 +143,9 @@ public:
void DropReference();
/**
* Finds the index of a given option element
* Finds the index of a given option element.
* If the option isn't part of the collection, return NS_ERROR_FAILURE
* without setting aIndex.
*
* @param aOption the option to get the index of
* @param aStartIndex the index to start looking at

View File

@ -64,6 +64,7 @@ _TEST_FILES = \
test_maxlength_attribute.html \
test_datalist_element.html \
test_form_attributes_reflection.html \
test_option_index_attribute.html \
$(NULL)
libs:: $(_TEST_FILES)

View File

@ -0,0 +1,76 @@
<!DOCTYPE HTML>
<html>
<!--
See those bugs:
https://bugzilla.mozilla.org/show_bug.cgi?id=720385
-->
<head>
<meta charset="utf-8">
<title>Test for option.index</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=720385">Mozilla Bug 720385</a>
<p id="display"></p>
<div id="content" style="display: none">
<datalist>
<option></option>
<option></option>
</datalist>
<select>
<option></option>
<foo>
<option></option>
<optgroup>
<option></option>
</optgroup>
<option></option>
</foo>
<option></option>
</select>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 720385 **/
var initialIndexes = [ 0, 0, 0, 1, 2, 3, 4 ];
var options = document.getElementsByTagName('option');
is(options.length, initialIndexes.length,
"Must have " + initialIndexes.length +" options");
for (var i=0; i<options.length; ++i) {
is(options[i].index, initialIndexes[i], "test");
}
var o = document.createElement('option');
is(o.index, 0, "option outside of a document have index=0");
document.body.appendChild(o);
is(o.index, 0, "option outside of a select have index=0");
var datalist = document.getElementsByTagName('datalist')[0];
datalist.appendChild(o);
is(o.index, 0, "option outside of a select have index=0");
datalist.removeChild(o);
is(o.index, 0, "option outside of a select have index=0");
var select = document.getElementsByTagName('select')[0];
select.appendChild(o);
is(o.index, 5, "option inside a select have an index");
select.removeChild(select.options[0]);
is(o.index, 4, "option inside a select have an index");
select.insertBefore(o, select.options[0]);
is(o.index, 0, "option inside a select have an index");
</script>
</pre>
</body>
</html>

View File

@ -5,7 +5,7 @@
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
</head>
<body>
<iframe name="submit_frame" onLoad="doCheck();"></iframe>
<iframe name="submit_frame"></iframe>
<form method="get" id="form1" target="submit_frame" action="../../../../../blah">
<table>
<tr><td>
@ -52,13 +52,14 @@
</table>
</form>
<script>
document.forms[0].submit();
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForExplicitFinish();
function doCheck(){
is(frames['submit_frame'].location.href, "http://mochi.test:8888/blah?field1-2=teststring&field2-2=0&field4-2=1&field6-2=3&field7-2=2&field8-2=8&field9-2=9&field12-2=&field1=teststring&field2=0&field4=1&field6=3&field7=2&field8=8&field9=9&field12=&field14=14&field14-2=14", "Submit string was correct.");
SimpleTest.finish();
}
frames['submit_frame'].onload = function() {
is(frames['submit_frame'].location.href, "http://mochi.test:8888/blah?field1-2=teststring&field2-2=0&field4-2=1&field6-2=3&field7-2=2&field8-2=8&field9-2=9&field12-2=&field1=teststring&field2=0&field4=1&field6=3&field7=2&field8=8&field9=9&field12=&field14=14&field14-2=14", "Submit string was correct.");
SimpleTest.finish();
}
document.forms[0].submit();
</script>
</body>
</html>

View File

@ -2200,11 +2200,8 @@ nsSMILTimedElement::GetNextMilestone(nsSMILMilestone& aNextMilestone) const
case STATE_POSTACTIVE:
return false;
default:
NS_ABORT_IF_FALSE(false, "Invalid element state");
return false;
}
MOZ_NOT_REACHED("Invalid element state");
}
void
@ -2275,11 +2272,8 @@ nsSMILTimedElement::GetEffectiveBeginInstance() const
const nsSMILInterval* prevInterval = GetPreviousInterval();
return prevInterval ? prevInterval->Begin() : nsnull;
}
default:
NS_NOTREACHED("Invalid element state");
return nsnull;
}
MOZ_NOT_REACHED("Invalid element state");
}
const nsSMILInterval*

View File

@ -164,6 +164,8 @@ DestroyMatchList(nsISupports* aKey, nsTemplateMatch*& aMatch, void* aContext)
nsXULTemplateBuilder::~nsXULTemplateBuilder(void)
{
Uninit(true);
if (--gRefCnt == 0) {
NS_IF_RELEASE(gRDFService);
NS_IF_RELEASE(gRDFContainerUtils);
@ -171,8 +173,6 @@ nsXULTemplateBuilder::~nsXULTemplateBuilder(void)
NS_IF_RELEASE(gScriptSecurityManager);
NS_IF_RELEASE(gObserverService);
}
Uninit(true);
}

View File

@ -4472,7 +4472,7 @@ nsDOMClassInfo::GetArrayIndexFromId(JSContext *cx, jsid id, bool *aIsNumber)
JSAutoRequest ar(cx);
jsval idval;
jsdouble array_index;
double array_index;
if (!::JS_IdToValue(cx, id, &idval) ||
!::JS_ValueToNumber(cx, idval, &array_index) ||
!::JS_DoubleIsInt32(array_index, &i)) {

View File

@ -1450,5 +1450,5 @@ nsresult
CountHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
return JS_NewNumberValue(aCx, static_cast<jsdouble>(mCount), aVal);
return JS_NewNumberValue(aCx, static_cast<double>(mCount), aVal);
}

View File

@ -900,7 +900,7 @@ SwapBytes(PRUint32 u)
#endif
}
static inline jsdouble
static inline double
SwapBytes(PRUint64 u)
{
#ifdef IS_BIG_ENDIAN
@ -913,7 +913,7 @@ SwapBytes(PRUint64 u)
((u & 0x00ff000000000000LLU) >> 40) |
((u & 0xff00000000000000LLU) >> 56);
#else
return jsdouble(u);
return double(u);
#endif
}
@ -2019,7 +2019,7 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
// This is a duplicate of the js engine's byte munging here
union {
jsdouble d;
double d;
PRUint64 u;
} pun;
@ -2851,5 +2851,5 @@ nsresult
CountHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
return JS_NewNumberValue(aCx, static_cast<jsdouble>(mCount), aVal);
return JS_NewNumberValue(aCx, static_cast<double>(mCount), aVal);
}

View File

@ -248,7 +248,7 @@ Key::DecodeJSVal(const unsigned char*& aPos, const unsigned char* aEnd,
}
}
else if (*aPos - aTypeOffset == eDate) {
jsdouble msec = static_cast<jsdouble>(DecodeNumber(aPos, aEnd));
double msec = static_cast<double>(DecodeNumber(aPos, aEnd));
JSObject* date = JS_NewDateObjectMsec(aCx, msec);
if (!date) {
NS_WARNING("Failed to make date!");

View File

@ -457,7 +457,7 @@ JSValToNPVariant(NPP npp, JSContext *cx, jsval val, NPVariant *variant)
} else if (JSVAL_IS_INT(val)) {
INT32_TO_NPVARIANT(JSVAL_TO_INT(val), *variant);
} else if (JSVAL_IS_DOUBLE(val)) {
jsdouble d = JSVAL_TO_DOUBLE(val);
double d = JSVAL_TO_DOUBLE(val);
jsint i;
if (JS_DoubleIsInt32(d, &i)) {
INT32_TO_NPVARIANT(i, *variant);

View File

@ -108,7 +108,7 @@ SmsMessage::Create(PRInt32 aId,
if (!aTimestamp.isNumber()) {
return NS_ERROR_INVALID_ARG;
}
jsdouble number = aTimestamp.toNumber();
double number = aTimestamp.toNumber();
if (static_cast<PRUint64>(number) != number) {
return NS_ERROR_INVALID_ARG;
}

View File

@ -41,13 +41,16 @@
#include "nsIDocument.h"
#include "nsIURI.h"
#include "nsIURL.h"
#include "nsPIDOMWindow.h"
#include "jsapi.h"
#include "mozilla/Preferences.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsContentUtils.h"
#include "nsDOMClassInfo.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsNetUtil.h"
#include "nsServiceManagerUtils.h"
#include "SystemWorkerManager.h"
@ -61,6 +64,10 @@ using mozilla::Preferences;
namespace {
typedef nsAutoTArray<Telephony*, 2> TelephonyList;
TelephonyList* gTelephonyList;
template <class T>
inline nsresult
nsTArrayToJSArray(JSContext* aCx, JSObject* aGlobal,
@ -110,6 +117,16 @@ nsTArrayToJSArray(JSContext* aCx, JSObject* aGlobal,
} // anonymous namespace
Telephony::Telephony()
: mActiveCall(nsnull), mCallsArray(nsnull), mRooted(false)
{
if (!gTelephonyList) {
gTelephonyList = new TelephonyList();
}
gTelephonyList->AppendElement(this);
}
Telephony::~Telephony()
{
if (mRIL && mRILTelephonyCallback) {
@ -119,6 +136,17 @@ Telephony::~Telephony()
if (mRooted) {
NS_DROP_JS_OBJECTS(this, Telephony);
}
NS_ASSERTION(gTelephonyList, "This should never be null!");
NS_ASSERTION(gTelephonyList->Contains(this), "Should be in the list!");
if (gTelephonyList->Length() == 1) {
delete gTelephonyList;
gTelephonyList = nsnull;
}
else {
gTelephonyList->RemoveElement(this);
}
}
// static
@ -150,14 +178,37 @@ Telephony::Create(nsPIDOMWindow* aOwner, nsIRadioInterfaceLayer* aRIL)
return telephony.forget();
}
void
Telephony::SwitchActiveCall(TelephonyCall* aCall)
already_AddRefed<TelephonyCall>
Telephony::CreateNewDialingCall(const nsAString& aNumber)
{
if (mActiveCall) {
// Put the call on hold?
NS_NOTYETIMPLEMENTED("Implement me!");
}
mActiveCall = aCall;
nsRefPtr<TelephonyCall> call =
TelephonyCall::Create(this, aNumber,
nsIRadioInterfaceLayer::CALL_STATE_DIALING);
NS_ASSERTION(call, "This should never fail!");
NS_ASSERTION(mCalls.Contains(call), "Should have auto-added new call!");
return call.forget();
}
void
Telephony::NoteDialedCallFromOtherInstance(const nsAString& aNumber)
{
// We don't need to hang on to this call object, it is held alive by mCalls.
nsRefPtr<TelephonyCall> call = CreateNewDialingCall(aNumber);
}
nsresult
Telephony::NotifyCallsChanged(TelephonyCall* aCall)
{
nsRefPtr<CallEvent> event = CallEvent::Create(aCall);
NS_ASSERTION(event, "This should never fail!");
nsresult rv =
event->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("callschanged"));
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMPL_CYCLE_COLLECTION_CLASS(Telephony)
@ -166,6 +217,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(Telephony,
nsDOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(incoming)
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(callschanged)
for (PRUint32 index = 0; index < tmp->mCalls.Length(); index++) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCalls[i]");
cb.NoteXPCOMChild(tmp->mCalls[index]->ToISupports());
@ -180,6 +232,7 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Telephony,
nsDOMEventTargetHelper)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(incoming)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(callschanged)
tmp->mCalls.Clear();
tmp->mActiveCall = nsnull;
tmp->mCallsArray = nsnull;
@ -216,11 +269,16 @@ Telephony::Dial(const nsAString& aNumber, nsIDOMTelephonyCall** aResult)
nsresult rv = mRIL->Dial(aNumber);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<TelephonyCall> call =
TelephonyCall::Create(this, aNumber, nsIRadioInterfaceLayer::CALL_STATE_DIALING);
NS_ASSERTION(call, "This should never fail!");
nsRefPtr<TelephonyCall> call = CreateNewDialingCall(aNumber);
NS_ASSERTION(mCalls.Contains(call), "Should have auto-added new call!");
// Notify other telephony objects that we just dialed.
for (PRUint32 index = 0; index < gTelephonyList->Length(); index++) {
Telephony*& telephony = gTelephonyList->ElementAt(index);
if (telephony != this) {
nsRefPtr<Telephony> kungFuDeathGrip = telephony;
telephony->NoteDialedCallFromOtherInstance(aNumber);
}
}
call.forget(aResult);
return NS_OK;
@ -279,32 +337,6 @@ Telephony::GetActive(jsval* aActive)
return NS_OK;
}
NS_IMETHODIMP
Telephony::SetActive(const jsval& aActive)
{
if (aActive.isObject()) {
nsIXPConnect* xpc = nsContentUtils::XPConnect();
NS_ASSERTION(xpc, "This should never be null!");
nsISupports* native =
xpc->GetNativeOfWrapper(mScriptContext->GetNativeContext(),
&aActive.toObject());
nsCOMPtr<nsIDOMTelephonyCall> call = do_QueryInterface(native);
if (call) {
// See if this call has the same telephony object. Otherwise we can't use
// it.
TelephonyCall* concreteCall = static_cast<TelephonyCall*>(call.get());
if (this == concreteCall->mTelephony) {
SwitchActiveCall(concreteCall);
return NS_OK;
}
}
}
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP
Telephony::GetCalls(jsval* aCalls)
{
@ -354,15 +386,8 @@ Telephony::StopTone()
return NS_OK;
}
NS_IMETHODIMP
Telephony::SendTones(const nsAString& aTones, PRUint32 aToneDuration,
PRUint32 aIntervalDuration)
{
NS_NOTYETIMPLEMENTED("Implement me!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMPL_EVENT_HANDLER(Telephony, incoming)
NS_IMPL_EVENT_HANDLER(Telephony, callschanged)
NS_IMETHODIMP
Telephony::CallStateChanged(PRUint32 aCallIndex, PRUint16 aCallState,
@ -378,7 +403,8 @@ Telephony::CallStateChanged(PRUint32 aCallIndex, PRUint16 aCallState,
nsRefPtr<TelephonyCall>& tempCall = mCalls[index];
if (tempCall->CallIndex() == kOutgoingPlaceholderCallIndex) {
NS_ASSERTION(!outgoingCall, "More than one outgoing call not supported!");
NS_ASSERTION(tempCall->CallState() == nsIRadioInterfaceLayer::CALL_STATE_DIALING,
NS_ASSERTION(tempCall->CallState() ==
nsIRadioInterfaceLayer::CALL_STATE_DIALING,
"Something really wrong here!");
// Stash this for later, we may need it if aCallIndex doesn't match one of
// our other calls.
@ -407,7 +433,7 @@ Telephony::CallStateChanged(PRUint32 aCallIndex, PRUint16 aCallState,
// See if this should replace our current active call.
if (aCallState == nsIRadioInterfaceLayer::CALL_STATE_CONNECTED) {
SwitchActiveCall(modifiedCall);
mActiveCall = modifiedCall;
}
return NS_OK;
@ -486,22 +512,48 @@ NS_NewTelephony(nsPIDOMWindow* aWindow, nsIDOMTelephony** aTelephony)
// Do security checks. We assume that chrome is always allowed and we also
// allow a single page specified by preferences.
if (!nsContentUtils::IsSystemPrincipal(document->NodePrincipal())) {
nsCOMPtr<nsIURI> documentURI;
nsCOMPtr<nsIURI> originalURI;
nsresult rv =
document->NodePrincipal()->GetURI(getter_AddRefs(documentURI));
document->NodePrincipal()->GetURI(getter_AddRefs(originalURI));
NS_ENSURE_SUCCESS(rv, rv);
nsCString documentURL;
rv = documentURI->GetSpec(documentURL);
nsCOMPtr<nsIURI> documentURI;
rv = originalURI->Clone(getter_AddRefs(documentURI));
NS_ENSURE_SUCCESS(rv, rv);
// Strip the query string (if there is one) before comparing.
nsCOMPtr<nsIURL> documentURL = do_QueryInterface(documentURI);
if (documentURL) {
rv = documentURL->SetQuery(EmptyCString());
NS_ENSURE_SUCCESS(rv, rv);
}
bool allowed = false;
// The pref may not exist but in that case we deny access just as we do if
// the url doesn't match.
nsCString phoneAppURL;
if (NS_FAILED(Preferences::GetCString(DOM_TELEPHONY_APP_PHONE_URL_PREF,
&phoneAppURL)) ||
!phoneAppURL.Equals(documentURL,
nsCaseInsensitiveCStringComparator())) {
nsCString whitelist;
if (NS_SUCCEEDED(Preferences::GetCString(DOM_TELEPHONY_APP_PHONE_URL_PREF,
&whitelist))) {
nsCOMPtr<nsIIOService> ios = do_GetIOService();
NS_ENSURE_TRUE(ios, NS_ERROR_FAILURE);
nsCCharSeparatedTokenizer tokenizer(whitelist, ',');
while (tokenizer.hasMoreTokens()) {
nsCOMPtr<nsIURI> uri;
if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), tokenizer.nextToken(),
nsnull, nsnull, ios))) {
rv = documentURI->EqualsExceptRef(uri, &allowed);
NS_ENSURE_SUCCESS(rv, rv);
if (allowed) {
break;
}
}
}
}
if (!allowed) {
*aTelephony = nsnull;
return NS_OK;
}

View File

@ -58,6 +58,7 @@ class Telephony : public nsDOMEventTargetHelper,
nsCOMPtr<nsIRILTelephonyCallback> mRILTelephonyCallback;
NS_DECL_EVENT_HANDLER(incoming)
NS_DECL_EVENT_HANDLER(callschanged)
TelephonyCall* mActiveCall;
nsTArray<nsRefPtr<TelephonyCall> > mCalls;
@ -99,6 +100,7 @@ public:
NS_ASSERTION(!mCalls.Contains(aCall), "Already know about this one!");
mCalls.AppendElement(aCall);
mCallsArray = nsnull;
NotifyCallsChanged(aCall);
}
void
@ -107,6 +109,7 @@ public:
NS_ASSERTION(mCalls.Contains(aCall), "Didn't know about this one!");
mCalls.RemoveElement(aCall);
mCallsArray = nsnull;
NotifyCallsChanged(aCall);
}
nsIRadioInterfaceLayer*
@ -128,14 +131,17 @@ public:
}
private:
Telephony()
: mActiveCall(nsnull), mCallsArray(nsnull), mRooted(false)
{ }
Telephony();
~Telephony();
already_AddRefed<TelephonyCall>
CreateNewDialingCall(const nsAString& aNumber);
void
SwitchActiveCall(TelephonyCall* aCall);
NoteDialedCallFromOtherInstance(const nsAString& aNumber);
nsresult
NotifyCallsChanged(TelephonyCall* aCall);
class RILTelephonyCallback : public nsIRILTelephonyCallback
{

View File

@ -43,7 +43,7 @@
interface nsIDOMEventListener;
interface nsIDOMTelephonyCall;
[scriptable, builtinclass, uuid(047be0d8-a9cd-49aa-8948-2f60ff3a7a18)]
[scriptable, builtinclass, uuid(0de46b73-be83-4970-ad15-45f92cb0902a)]
interface nsIDOMTelephony : nsIDOMEventTarget
{
nsIDOMTelephonyCall dial(in DOMString number);
@ -53,16 +53,14 @@ interface nsIDOMTelephony : nsIDOMEventTarget
// The call that is "active", i.e. receives microphone input and tones
// generated via startTone.
attribute jsval active;
readonly attribute jsval active;
// Array of all calls that are currently connected.
readonly attribute jsval calls;
void startTone(in DOMString tone);
void stopTone();
void sendTones(in DOMString tones,
[optional] in unsigned long toneDuration,
[optional] in unsigned long intervalDuration);
attribute nsIDOMEventListener onincoming;
attribute nsIDOMEventListener oncallschanged;
};

View File

@ -850,7 +850,7 @@ public:
static JSObject*
Create(JSContext* aCx, JSObject* aParent, JSString* aType,
bool aLengthComputable, jsdouble aLoaded, jsdouble aTotal)
bool aLengthComputable, double aLoaded, double aTotal)
{
JSString* type = JS_InternJSString(aCx, aType);
if (!type) {
@ -907,8 +907,8 @@ private:
static void
InitProgressEventCommon(JSObject* aObj, Event* aEvent, JSString* aType,
JSBool aBubbles, JSBool aCancelable,
JSBool aLengthComputable, jsdouble aLoaded,
jsdouble aTotal, bool aIsTrusted)
JSBool aLengthComputable, double aLoaded,
double aTotal, bool aIsTrusted)
{
Event::InitEventCommon(aObj, aEvent, aType, aBubbles, aCancelable,
aIsTrusted);
@ -967,7 +967,7 @@ private:
JSString* type;
JSBool bubbles, cancelable, lengthComputable;
jsdouble loaded, total;
double loaded, total;
if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "Sbbbdd", &type,
&bubbles, &cancelable, &lengthComputable, &loaded,
&total)) {
@ -1065,7 +1065,7 @@ CreateErrorEvent(JSContext* aCx, JSString* aMessage, JSString* aFilename,
JSObject*
CreateProgressEvent(JSContext* aCx, JSString* aType, bool aLengthComputable,
jsdouble aLoaded, jsdouble aTotal)
double aLoaded, double aTotal)
{
JSObject* global = JS_GetGlobalForScopeChain(aCx);
return ProgressEvent::Create(aCx, global, aType, aLengthComputable, aLoaded,

View File

@ -69,7 +69,7 @@ CreateErrorEvent(JSContext* aCx, JSString* aMessage, JSString* aFilename,
JSObject*
CreateProgressEvent(JSContext* aCx, JSString* aType, bool aLengthComputable,
jsdouble aLoaded, jsdouble aTotal);
double aLoaded, double aTotal);
bool
IsSupportedEventClass(JSObject* aEvent);

View File

@ -140,7 +140,7 @@ private:
ThrowFileExceptionForCode(aCx, FILE_NOT_READABLE_ERR);
}
if (!JS_NewNumberValue(aCx, jsdouble(size), aVp)) {
if (!JS_NewNumberValue(aCx, double(size), aVp)) {
return false;
}
@ -183,7 +183,7 @@ private:
return false;
}
jsdouble start = 0, end = 0;
double start = 0, end = 0;
JSString* jsContentType = JS_GetEmptyString(JS_GetRuntime(aCx));
if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "/IIS", &start,
&end, &jsContentType)) {

View File

@ -3533,7 +3533,7 @@ WorkerPrivate::SetTimeout(JSContext* aCx, uintN aArgc, jsval* aVp,
// See if any of the optional arguments were passed.
if (aArgc > 1) {
jsdouble intervalMS = 0;
double intervalMS = 0;
if (!JS_ValueToNumber(aCx, argv[1], &intervalMS)) {
return false;
}

View File

@ -10,6 +10,8 @@ In this order:
angle-limit-identifiers-to-250-chars.patch - see bug 675625
angle-use-xmalloc.patch - see bug 680840. Can drop this patch whenever the new preprocessor lands.
angle-castrate-bug-241.patch - see bug 699033 / angle bug 241
angle-enforce-readpixels-spec.patch - see bug 724476.
angle-impl-read-bgra.patch - see bug 724476.
In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.

View File

@ -0,0 +1,34 @@
From: Jeff Gilbert <jgilbert@mozilla.com>
Bug 724476 - ANGLE Bug 293 - Enforce readPixels format/type semantics
diff --git a/gfx/angle/src/libGLESv2/libGLESv2.cpp b/gfx/angle/src/libGLESv2/libGLESv2.cpp
--- a/gfx/angle/src/libGLESv2/libGLESv2.cpp
+++ b/gfx/angle/src/libGLESv2/libGLESv2.cpp
@@ -98,27 +98,16 @@ bool validReadFormatType(GLenum format,
switch (type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return false;
}
break;
- case GL_BGRA_EXT:
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
- break;
- default:
- return false;
- }
- break;
case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
switch (type)
{
case gl::IMPLEMENTATION_COLOR_READ_TYPE:
break;
default:
return false;
}

View File

@ -0,0 +1,71 @@
From: Jeff Gilbert <jgilbert@mozilla.com>
Bug 724476 - ANGLE Bug 294 - Use BGRA/UBYTE as exposed fast format/type for readPixels
diff --git a/gfx/angle/src/libGLESv2/Context.cpp b/gfx/angle/src/libGLESv2/Context.cpp
--- a/gfx/angle/src/libGLESv2/Context.cpp
+++ b/gfx/angle/src/libGLESv2/Context.cpp
@@ -2520,16 +2520,17 @@ void Context::readPixels(GLint x, GLint
{
if (desc.Format == D3DFMT_A8R8G8B8 &&
format == GL_BGRA_EXT &&
type == GL_UNSIGNED_BYTE)
{
// Fast path for EXT_read_format_bgra, given
// an RGBA source buffer. Note that buffers with no
// alpha go through the slow path below.
+ // Note that this is also the combo exposed by IMPLEMENTATION_COLOR_READ_TYPE/FORMAT
memcpy(dest + j * outputPitch,
source + j * inputPitch,
(rect.right - rect.left) * 4);
continue;
}
for (int i = 0; i < rect.right - rect.left; i++)
{
@@ -2666,20 +2667,20 @@ void Context::readPixels(GLint x, GLint
((unsigned short)( a + 0.5f) << 15) |
((unsigned short)(31 * r + 0.5f) << 10) |
((unsigned short)(31 * g + 0.5f) << 5) |
((unsigned short)(31 * b + 0.5f) << 0);
break;
default: UNREACHABLE();
}
break;
- case GL_RGB: // IMPLEMENTATION_COLOR_READ_FORMAT
+ case GL_RGB:
switch (type)
{
- case GL_UNSIGNED_SHORT_5_6_5: // IMPLEMENTATION_COLOR_READ_TYPE
+ case GL_UNSIGNED_SHORT_5_6_5:
dest16[i + j * outputPitch / sizeof(unsigned short)] =
((unsigned short)(31 * b + 0.5f) << 0) |
((unsigned short)(63 * g + 0.5f) << 5) |
((unsigned short)(31 * r + 0.5f) << 11);
break;
default: UNREACHABLE();
}
break;
diff --git a/gfx/angle/src/libGLESv2/Context.h b/gfx/angle/src/libGLESv2/Context.h
--- a/gfx/angle/src/libGLESv2/Context.h
+++ b/gfx/angle/src/libGLESv2/Context.h
@@ -69,18 +69,18 @@ enum
MAX_VARYING_VECTORS_SM3 = 10,
MAX_TEXTURE_IMAGE_UNITS = 16,
MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF = 4, // For devices supporting vertex texture fetch
MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF,
MAX_FRAGMENT_UNIFORM_VECTORS_SM2 = 32 - 3, // Reserve space for dx_Coord, dx_Depth, and dx_DepthRange. dx_PointOrLines and dx_FrontCCW use separate bool registers.
MAX_FRAGMENT_UNIFORM_VECTORS_SM3 = 224 - 3,
MAX_DRAW_BUFFERS = 1,
- IMPLEMENTATION_COLOR_READ_FORMAT = GL_RGB,
- IMPLEMENTATION_COLOR_READ_TYPE = GL_UNSIGNED_SHORT_5_6_5
+ IMPLEMENTATION_COLOR_READ_FORMAT = GL_BGRA_EXT,
+ IMPLEMENTATION_COLOR_READ_TYPE = GL_UNSIGNED_BYTE
};
enum QueryType
{
QUERY_ANY_SAMPLES_PASSED,
QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE,
QUERY_TYPE_COUNT

View File

@ -2525,6 +2525,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
// Fast path for EXT_read_format_bgra, given
// an RGBA source buffer. Note that buffers with no
// alpha go through the slow path below.
// Note that this is also the combo exposed by IMPLEMENTATION_COLOR_READ_TYPE/FORMAT
memcpy(dest + j * outputPitch,
source + j * inputPitch,
(rect.right - rect.left) * 4);
@ -2671,10 +2672,10 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
default: UNREACHABLE();
}
break;
case GL_RGB: // IMPLEMENTATION_COLOR_READ_FORMAT
case GL_RGB:
switch (type)
{
case GL_UNSIGNED_SHORT_5_6_5: // IMPLEMENTATION_COLOR_READ_TYPE
case GL_UNSIGNED_SHORT_5_6_5:
dest16[i + j * outputPitch / sizeof(unsigned short)] =
((unsigned short)(31 * b + 0.5f) << 0) |
((unsigned short)(63 * g + 0.5f) << 5) |

View File

@ -74,8 +74,8 @@ enum
MAX_FRAGMENT_UNIFORM_VECTORS_SM3 = 224 - 3,
MAX_DRAW_BUFFERS = 1,
IMPLEMENTATION_COLOR_READ_FORMAT = GL_RGB,
IMPLEMENTATION_COLOR_READ_TYPE = GL_UNSIGNED_SHORT_5_6_5
IMPLEMENTATION_COLOR_READ_FORMAT = GL_BGRA_EXT,
IMPLEMENTATION_COLOR_READ_TYPE = GL_UNSIGNED_BYTE
};
enum QueryType

View File

@ -103,17 +103,6 @@ bool validReadFormatType(GLenum format, GLenum type)
return false;
}
break;
case GL_BGRA_EXT:
switch (type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
break;
default:
return false;
}
break;
case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
switch (type)
{

View File

@ -1,6 +1,6 @@
This is the Sanitiser for OpenType project, from http://code.google.com/p/ots/.
Current revision: r77
Current revision: r81
Applied local patches:
ots-fix-vc10.patch - workaround for VS10 STL wrappers (bug 602558)

View File

@ -77,8 +77,9 @@ class OTSStream {
}
if (chksum_buffer_offset_ == 4) {
// TODO(yusukes): This cast breaks the strict-aliasing rule.
chksum_ += ntohl(*reinterpret_cast<const uint32_t*>(chksum_buffer_));
uint32_t chksum;
std::memcpy(&chksum, chksum_buffer_, 4);
chksum_ += ntohl(chksum);
chksum_buffer_offset_ = 0;
}

View File

@ -760,14 +760,13 @@ bool ParseDictData(const uint8_t *data, size_t table_length,
return OTS_FAILURE();
}
const uint32_t private_length = operands.back().first;
if (private_offset >= table_length) {
if (private_offset > table_length) {
return OTS_FAILURE();
}
if (private_length >= table_length) {
return OTS_FAILURE();
}
if (private_length + private_offset > table_length) {
// does not overflow since table_length < 1GB
return OTS_FAILURE();
}
// parse "15. Private DICT Data"

View File

@ -10,6 +10,7 @@
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <map>
#include <vector>
@ -28,9 +29,12 @@ struct OpenTypeTable {
uint32_t uncompressed_length;
};
// Round a value up to the nearest multiple of 4. Note that this can overflow
// and return zero.
// Round a value up to the nearest multiple of 4. Don't round the value in the
// case that rounding up overflows.
template<typename T> T Round4(T value) {
if (std::numeric_limits<T>::max() - value < 3) {
return value;
}
return (value + 3) & ~3;
}
@ -280,7 +284,7 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
return OTS_FAILURE();
}
if (!file.ReadU16(&header->num_tables)) {
if (!file.ReadU16(&header->num_tables) || !header->num_tables) {
return OTS_FAILURE();
}
@ -289,18 +293,52 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
return OTS_FAILURE();
}
// We don't care about these fields of the header:
// uint32_t uncompressed_size;
// uint16_t major_version, minor_version
// uint32_t meta_offset, meta_length, meta_length_orig
// uint32_t priv_offset, priv_length
if (!file.Skip(6 * 4 + 2 * 2)) {
uint32_t reported_total_sfnt_size;
if (!file.ReadU32(&reported_total_sfnt_size)) {
return OTS_FAILURE();
}
// We don't care about these fields of the header:
// uint16_t major_version, minor_version
if (!file.Skip(2 * 2)) {
return OTS_FAILURE();
}
// Checks metadata block size.
uint32_t meta_offset;
uint32_t meta_length;
uint32_t meta_length_orig;
if (!file.ReadU32(&meta_offset) ||
!file.ReadU32(&meta_length) ||
!file.ReadU32(&meta_length_orig)) {
return OTS_FAILURE();
}
if (meta_offset) {
if (meta_offset >= length || length - meta_offset < meta_length) {
return OTS_FAILURE();
}
}
// Checks private data block size.
uint32_t priv_offset;
uint32_t priv_length;
if (!file.ReadU32(&priv_offset) ||
!file.ReadU32(&priv_length)) {
return OTS_FAILURE();
}
if (priv_offset) {
if (priv_offset >= length || length - priv_offset < priv_length) {
return OTS_FAILURE();
}
}
// Next up is the list of tables.
std::vector<OpenTypeTable> tables;
uint32_t first_index = 0;
uint32_t last_index = 0;
// Size of sfnt header plus size of table records.
uint64_t total_sfnt_size = 12 + 16 * header->num_tables;
for (unsigned i = 0; i < header->num_tables; ++i) {
OpenTypeTable table;
if (!file.ReadTag(&table.tag) ||
@ -311,7 +349,60 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
return OTS_FAILURE();
}
total_sfnt_size += Round4(table.uncompressed_length);
if (total_sfnt_size > std::numeric_limits<uint32_t>::max()) {
return OTS_FAILURE();
}
tables.push_back(table);
if (i == 0 || tables[first_index].offset > table.offset)
first_index = i;
if (i == 0 || tables[last_index].offset < table.offset)
last_index = i;
}
if (reported_total_sfnt_size != total_sfnt_size) {
return OTS_FAILURE();
}
// Table data must follow immediately after the header.
if (tables[first_index].offset != Round4(file.offset())) {
return OTS_FAILURE();
}
if (tables[last_index].offset >= length ||
length - tables[last_index].offset < tables[last_index].length) {
return OTS_FAILURE();
}
// Blocks must follow immediately after the previous block.
// (Except for padding with a maximum of three null bytes)
uint64_t block_end = Round4(
static_cast<uint64_t>(tables[last_index].offset) +
static_cast<uint64_t>(tables[last_index].length));
if (block_end > std::numeric_limits<uint32_t>::max()) {
return OTS_FAILURE();
}
if (meta_offset) {
if (block_end != meta_offset) {
return OTS_FAILURE();
}
block_end = Round4(static_cast<uint64_t>(meta_offset) +
static_cast<uint64_t>(meta_length));
if (block_end > std::numeric_limits<uint32_t>::max()) {
return OTS_FAILURE();
}
}
if (priv_offset) {
if (block_end != priv_offset) {
return OTS_FAILURE();
}
block_end = Round4(static_cast<uint64_t>(priv_offset) +
static_cast<uint64_t>(priv_length));
if (block_end > std::numeric_limits<uint32_t>::max()) {
return OTS_FAILURE();
}
}
if (block_end != Round4(length)) {
return OTS_FAILURE();
}
return ProcessGeneric(header, output, data, length, tables, file);
@ -378,11 +469,11 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
}
// since we required that the file be < 1GB in length, and that the table
// length is < 1GB, the following addtion doesn't overflow
const uint32_t end_byte = Round4(tables[i].offset + tables[i].length);
const uint32_t end_byte = tables[i].offset + tables[i].length;
// Some fonts which are automatically generated by a font generator
// called TTX seems not to add 0-padding to the final table. It might be
// ok to accept these fonts so we round up the length of the font file.
if (!end_byte || end_byte > Round4(length)) {
if (!end_byte || end_byte > length) {
return OTS_FAILURE();
}
}

View File

@ -122,9 +122,8 @@ inline gfxContext::GraphicsLineCap ThebesLineCap(CapStyle aStyle)
return gfxContext::LINE_CAP_ROUND;
case CAP_SQUARE:
return gfxContext::LINE_CAP_SQUARE;
default:
return gfxContext::LINE_CAP_BUTT;
}
MOZ_NOT_REACHED("Incomplete switch");
}
inline CapStyle ToCapStyle(gfxContext::GraphicsLineCap aStyle)
@ -136,9 +135,8 @@ inline CapStyle ToCapStyle(gfxContext::GraphicsLineCap aStyle)
return CAP_ROUND;
case gfxContext::LINE_CAP_SQUARE:
return CAP_SQUARE;
default:
return CAP_BUTT;
}
MOZ_NOT_REACHED("Incomplete switch");
}
inline gfxContext::GraphicsLineJoin ThebesLineJoin(JoinStyle aStyle)
@ -164,9 +162,8 @@ inline JoinStyle ToJoinStyle(gfxContext::GraphicsLineJoin aStyle)
return JOIN_BEVEL;
case gfxContext::LINE_JOIN_ROUND:
return JOIN_ROUND;
default:
return JOIN_MITER;
}
MOZ_NOT_REACHED("Incomplete switch");
}
inline gfxMatrix ThebesMatrix(const Matrix &aMatrix)

View File

@ -160,10 +160,8 @@ GetBackendName(mozilla::gfx::BackendType aBackend)
return "skia";
case mozilla::gfx::BACKEND_NONE:
return "none";
default:
NS_ERROR("Invalid backend type!");
return "";
}
MOZ_NOT_REACHED("Incomplet switch");
}
class THEBES_API gfxPlatform {

View File

@ -45,6 +45,7 @@
#include "nsDebug.h"
#include "mozilla/gfx/BaseMargin.h"
#include "mozilla/gfx/BaseRect.h"
#include "mozilla/Assertions.h"
#include "nsRect.h"
struct gfxMargin : public mozilla::gfx::BaseMargin<gfxFloat, gfxMargin> {
@ -126,11 +127,8 @@ struct THEBES_API gfxRect :
case NS_SIDE_RIGHT: return TopRight();
case NS_SIDE_BOTTOM: return BottomRight();
case NS_SIDE_LEFT: return BottomLeft();
default:
NS_ERROR("Invalid side!");
break;
}
return gfxPoint(0.0, 0.0);
MOZ_NOT_REACHED("Incomplet switch");
}
gfxPoint CWCorner(mozilla::css::Side side) const {
@ -139,11 +137,8 @@ struct THEBES_API gfxRect :
case NS_SIDE_RIGHT: return BottomRight();
case NS_SIDE_BOTTOM: return BottomLeft();
case NS_SIDE_LEFT: return TopLeft();
default:
NS_ERROR("Invalid side!");
break;
}
return gfxPoint(0.0, 0.0);
MOZ_NOT_REACHED("Incomplet switch");
}
/* Conditions this border to Cairo's max coordinate space.

View File

@ -55,8 +55,8 @@ union JSVariant {
nsString;
int;
double;
bool; // We'd like to use JSBool here, but JSBool is really JSIntn,
// and IPC::ParamTraits mistakes JSIntn for int.
bool; // We'd like to use JSBool here, but IPC::ParamTraits would
// treat JSBool as int.
};
union OperationStatus {

View File

@ -210,12 +210,12 @@ struct JSDProfileData
uintN callCount;
uintN recurseDepth;
uintN maxRecurseDepth;
jsdouble minExecutionTime;
jsdouble maxExecutionTime;
jsdouble totalExecutionTime;
jsdouble minOwnExecutionTime;
jsdouble maxOwnExecutionTime;
jsdouble totalOwnExecutionTime;
double minExecutionTime;
double maxExecutionTime;
double totalExecutionTime;
double minOwnExecutionTime;
double maxOwnExecutionTime;
double totalOwnExecutionTime;
};
struct JSDSourceText
@ -417,22 +417,22 @@ jsd_GetScriptCallCount(JSDContext* jsdc, JSDScript *script);
extern uintN
jsd_GetScriptMaxRecurseDepth(JSDContext* jsdc, JSDScript *script);
extern jsdouble
extern double
jsd_GetScriptMinExecutionTime(JSDContext* jsdc, JSDScript *script);
extern jsdouble
extern double
jsd_GetScriptMaxExecutionTime(JSDContext* jsdc, JSDScript *script);
extern jsdouble
extern double
jsd_GetScriptTotalExecutionTime(JSDContext* jsdc, JSDScript *script);
extern jsdouble
extern double
jsd_GetScriptMinOwnExecutionTime(JSDContext* jsdc, JSDScript *script);
extern jsdouble
extern double
jsd_GetScriptMaxOwnExecutionTime(JSDContext* jsdc, JSDScript *script);
extern jsdouble
extern double
jsd_GetScriptTotalOwnExecutionTime(JSDContext* jsdc, JSDScript *script);
extern void
@ -972,7 +972,7 @@ jsd_GetValueBoolean(JSDContext* jsdc, JSDValue* jsdval);
extern int32_t
jsd_GetValueInt(JSDContext* jsdc, JSDValue* jsdval);
extern jsdouble
extern double
jsd_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval);
extern JSString*

View File

@ -367,7 +367,7 @@ jsd_GetScriptMaxRecurseDepth(JSDContext* jsdc, JSDScript *script)
return 0;
}
jsdouble
double
jsd_GetScriptMinExecutionTime(JSDContext* jsdc, JSDScript *script)
{
if (script->profileData)
@ -376,7 +376,7 @@ jsd_GetScriptMinExecutionTime(JSDContext* jsdc, JSDScript *script)
return 0.0;
}
jsdouble
double
jsd_GetScriptMaxExecutionTime(JSDContext* jsdc, JSDScript *script)
{
if (script->profileData)
@ -385,7 +385,7 @@ jsd_GetScriptMaxExecutionTime(JSDContext* jsdc, JSDScript *script)
return 0.0;
}
jsdouble
double
jsd_GetScriptTotalExecutionTime(JSDContext* jsdc, JSDScript *script)
{
if (script->profileData)
@ -394,7 +394,7 @@ jsd_GetScriptTotalExecutionTime(JSDContext* jsdc, JSDScript *script)
return 0.0;
}
jsdouble
double
jsd_GetScriptMinOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
if (script->profileData)
@ -403,7 +403,7 @@ jsd_GetScriptMinOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
return 0.0;
}
jsdouble
double
jsd_GetScriptMaxOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
if (script->profileData)
@ -412,7 +412,7 @@ jsd_GetScriptMaxOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
return 0.0;
}
jsdouble
double
jsd_GetScriptTotalOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
if (script->profileData)

View File

@ -187,7 +187,7 @@ _callHook(JSDContext *jsdc, JSContext *cx, JSStackFrame *fp, JSBool before,
hookresult = JS_TRUE;
} else if (!pdata->recurseDepth && pdata->lastCallStart) {
int64_t now, ll_delta;
jsdouble delta;
double delta;
now = JS_Now();
ll_delta = now - pdata->lastCallStart;
delta = ll_delta;

View File

@ -197,7 +197,7 @@ jsd_GetValueInt(JSDContext* jsdc, JSDValue* jsdval)
return JSVAL_TO_INT(val);
}
jsdouble
double
jsd_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval)
{
if(!JSVAL_IS_DOUBLE(jsdval->val))

View File

@ -211,42 +211,42 @@ JSD_GetScriptMaxRecurseDepth(JSDContext* jsdc, JSDScript *script)
}
JSD_PUBLIC_API(jsdouble)
JSD_PUBLIC_API(double)
JSD_GetScriptMinExecutionTime(JSDContext* jsdc, JSDScript *script)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_GetScriptMinExecutionTime(jsdc, script);
}
JSD_PUBLIC_API(jsdouble)
JSD_PUBLIC_API(double)
JSD_GetScriptMaxExecutionTime(JSDContext* jsdc, JSDScript *script)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_GetScriptMaxExecutionTime(jsdc, script);
}
JSD_PUBLIC_API(jsdouble)
JSD_PUBLIC_API(double)
JSD_GetScriptTotalExecutionTime(JSDContext* jsdc, JSDScript *script)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_GetScriptTotalExecutionTime(jsdc, script);
}
JSD_PUBLIC_API(jsdouble)
JSD_PUBLIC_API(double)
JSD_GetScriptMinOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_GetScriptMinOwnExecutionTime(jsdc, script);
}
JSD_PUBLIC_API(jsdouble)
JSD_PUBLIC_API(double)
JSD_GetScriptMaxOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_GetScriptMaxOwnExecutionTime(jsdc, script);
}
JSD_PUBLIC_API(jsdouble)
JSD_PUBLIC_API(double)
JSD_GetScriptTotalOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
@ -1110,7 +1110,7 @@ JSD_GetValueInt(JSDContext* jsdc, JSDValue* jsdval)
return jsd_GetValueInt(jsdc, jsdval);
}
JSD_PUBLIC_API(jsdouble)
JSD_PUBLIC_API(double)
JSD_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);

View File

@ -333,40 +333,40 @@ JSD_GetScriptMaxRecurseDepth(JSDContext* jsdc, JSDScript *script);
/*
* Get the shortest execution time recorded.
*/
extern JSD_PUBLIC_API(jsdouble)
extern JSD_PUBLIC_API(double)
JSD_GetScriptMinExecutionTime(JSDContext* jsdc, JSDScript *script);
/*
* Get the longest execution time recorded.
*/
extern JSD_PUBLIC_API(jsdouble)
extern JSD_PUBLIC_API(double)
JSD_GetScriptMaxExecutionTime(JSDContext* jsdc, JSDScript *script);
/*
* Get the total amount of time spent in this script.
*/
extern JSD_PUBLIC_API(jsdouble)
extern JSD_PUBLIC_API(double)
JSD_GetScriptTotalExecutionTime(JSDContext* jsdc, JSDScript *script);
/*
* Get the shortest execution time recorded, excluding time spent in called
* functions.
*/
extern JSD_PUBLIC_API(jsdouble)
extern JSD_PUBLIC_API(double)
JSD_GetScriptMinOwnExecutionTime(JSDContext* jsdc, JSDScript *script);
/*
* Get the longest execution time recorded, excluding time spent in called
* functions.
*/
extern JSD_PUBLIC_API(jsdouble)
extern JSD_PUBLIC_API(double)
JSD_GetScriptMaxOwnExecutionTime(JSDContext* jsdc, JSDScript *script);
/*
* Get the total amount of time spent in this script, excluding time spent
* in called functions.
*/
extern JSD_PUBLIC_API(jsdouble)
extern JSD_PUBLIC_API(double)
JSD_GetScriptTotalOwnExecutionTime(JSDContext* jsdc, JSDScript *script);
/*
@ -1293,7 +1293,7 @@ JSD_GetValueInt(JSDContext* jsdc, JSDValue* jsdval);
* Return double value (does NOT do conversion).
* *** new for version 1.1 ****
*/
extern JSD_PUBLIC_API(jsdouble)
extern JSD_PUBLIC_API(double)
JSD_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval);
/*

View File

@ -154,6 +154,7 @@ CPPSRCS = \
Debugger.cpp \
GlobalObject.cpp \
MethodGuard.cpp \
ObjectImpl.cpp \
Stack.cpp \
String.cpp \
BytecodeCompiler.cpp \

View File

@ -94,6 +94,8 @@ RandomizeIsBrokenImpl()
static bool
RandomizeIsBroken()
{
// Use the compiler's intrinsic guards for |static type value = expr| to avoid some potential
// races if runtimes are created from multiple threads.
static int result = RandomizeIsBrokenImpl();
return !!result;
}

View File

@ -86,7 +86,7 @@ HashableValue::setValue(JSContext *cx, const Value &v)
return false;
value = StringValue(str);
} else if (v.isDouble()) {
jsdouble d = v.toDouble();
double d = v.toDouble();
int32_t i;
if (JSDOUBLE_IS_INT32(d, &i)) {
/* Normalize int32-valued doubles to int32 for faster hashing and testing. */

View File

@ -602,7 +602,7 @@ ExecuteRegExp(JSContext *cx, Native native, uintN argc, Value *vp)
const Value &lastIndex = reobj.getLastIndex();
/* Step 5. */
jsdouble i;
double i;
if (!ToInteger(cx, lastIndex, &i))
return false;

View File

@ -457,7 +457,7 @@ static JSFunctionSpec sModuleFunctions[] = {
JS_FS_END
};
static inline bool FloatIsFinite(jsdouble f) {
static inline bool FloatIsFinite(double f) {
#ifdef WIN32
return _finite(f) != 0;
#else
@ -1004,8 +1004,8 @@ struct ConvertImpl {
// MSVC can't perform double to unsigned __int64 conversion when the
// double is greater than 2^63 - 1. Help it along a little.
template<>
struct ConvertImpl<uint64_t, jsdouble> {
static JS_ALWAYS_INLINE uint64_t Convert(jsdouble d) {
struct ConvertImpl<uint64_t, double> {
static JS_ALWAYS_INLINE uint64_t Convert(double d) {
return d > 0x7fffffffffffffffui64 ?
uint64_t(d - 0x8000000000000000ui64) + 0x8000000000000000ui64 :
uint64_t(d);
@ -1020,16 +1020,16 @@ struct ConvertImpl<uint64_t, jsdouble> {
#ifdef SPARC
// Simulate x86 overflow behavior
template<>
struct ConvertImpl<uint64_t, jsdouble> {
static JS_ALWAYS_INLINE uint64_t Convert(jsdouble d) {
struct ConvertImpl<uint64_t, double> {
static JS_ALWAYS_INLINE uint64_t Convert(double d) {
return d >= 0xffffffffffffffff ?
0x8000000000000000 : uint64_t(d);
}
};
template<>
struct ConvertImpl<int64_t, jsdouble> {
static JS_ALWAYS_INLINE int64_t Convert(jsdouble d) {
struct ConvertImpl<int64_t, double> {
static JS_ALWAYS_INLINE int64_t Convert(double d) {
return d >= 0x7fffffffffffffff ?
0x8000000000000000 : int64_t(d);
}
@ -1141,7 +1141,7 @@ static JS_ALWAYS_INLINE bool IsNegative(Type i)
return IsNegativeImpl<Type, numeric_limits<Type>::is_signed>::Test(i);
}
// Implicitly convert val to bool, allowing JSBool, jsint, and jsdouble
// Implicitly convert val to bool, allowing JSBool, jsint, and double
// arguments numerically equal to 0 or 1.
static bool
jsvalToBool(JSContext* cx, jsval val, bool* result)
@ -1156,7 +1156,7 @@ jsvalToBool(JSContext* cx, jsval val, bool* result)
return i == 0 || i == 1;
}
if (JSVAL_IS_DOUBLE(val)) {
jsdouble d = JSVAL_TO_DOUBLE(val);
double d = JSVAL_TO_DOUBLE(val);
*result = d != 0;
// Allow -0.
return d == 1 || d == 0;
@ -1165,7 +1165,7 @@ jsvalToBool(JSContext* cx, jsval val, bool* result)
return false;
}
// Implicitly convert val to IntegerType, allowing JSBool, jsint, jsdouble,
// Implicitly convert val to IntegerType, allowing JSBool, jsint, double,
// Int64, UInt64, and CData integer types 't' where all values of 't' are
// representable by IntegerType.
template<class IntegerType>
@ -1183,7 +1183,7 @@ jsvalToInteger(JSContext* cx, jsval val, IntegerType* result)
if (JSVAL_IS_DOUBLE(val)) {
// Don't silently lose bits here -- check that val really is an
// integer value, and has the right sign.
jsdouble d = JSVAL_TO_DOUBLE(val);
double d = JSVAL_TO_DOUBLE(val);
return ConvertExact(d, result);
}
if (!JSVAL_IS_PRIMITIVE(val)) {
@ -1246,7 +1246,7 @@ jsvalToInteger(JSContext* cx, jsval val, IntegerType* result)
return false;
}
// Implicitly convert val to FloatType, allowing jsint, jsdouble,
// Implicitly convert val to FloatType, allowing jsint, double,
// Int64, UInt64, and CData numeric types 't' where all values of 't' are
// representable by FloatType.
template<class FloatType>
@ -1359,7 +1359,7 @@ StringToInteger(JSContext* cx, JSString* string, IntegerType* result)
return true;
}
// Implicitly convert val to IntegerType, allowing jsint, jsdouble,
// Implicitly convert val to IntegerType, allowing jsint, double,
// Int64, UInt64, and optionally a decimal or hexadecimal string argument.
// (This is common code shared by jsvalToSize and the Int64/UInt64 constructors.)
template<class IntegerType>
@ -1380,7 +1380,7 @@ jsvalToBigInteger(JSContext* cx,
if (JSVAL_IS_DOUBLE(val)) {
// Don't silently lose bits here -- check that val really is an
// integer value, and has the right sign.
jsdouble d = JSVAL_TO_DOUBLE(val);
double d = JSVAL_TO_DOUBLE(val);
return ConvertExact(d, result);
}
if (allowString && JSVAL_IS_STRING(val)) {
@ -1410,18 +1410,18 @@ jsvalToBigInteger(JSContext* cx,
}
// Implicitly convert val to a size value, where the size value is represented
// by size_t but must also fit in a jsdouble.
// by size_t but must also fit in a double.
static bool
jsvalToSize(JSContext* cx, jsval val, bool allowString, size_t* result)
{
if (!jsvalToBigInteger(cx, val, allowString, result))
return false;
// Also check that the result fits in a jsdouble.
return Convert<size_t>(jsdouble(*result)) == *result;
// Also check that the result fits in a double.
return Convert<size_t>(double(*result)) == *result;
}
// Implicitly convert val to IntegerType, allowing jsint, jsdouble,
// Implicitly convert val to IntegerType, allowing jsint, double,
// Int64, UInt64, and optionally a decimal or hexadecimal string argument.
// (This is common code shared by jsvalToSize and the Int64/UInt64 constructors.)
template<class IntegerType>
@ -1466,28 +1466,28 @@ jsidToBigInteger(JSContext* cx,
}
// Implicitly convert val to a size value, where the size value is represented
// by size_t but must also fit in a jsdouble.
// by size_t but must also fit in a double.
static bool
jsidToSize(JSContext* cx, jsid val, bool allowString, size_t* result)
{
if (!jsidToBigInteger(cx, val, allowString, result))
return false;
// Also check that the result fits in a jsdouble.
return Convert<size_t>(jsdouble(*result)) == *result;
// Also check that the result fits in a double.
return Convert<size_t>(double(*result)) == *result;
}
// Implicitly convert a size value to a jsval, ensuring that the size_t value
// fits in a jsdouble.
// fits in a double.
static JSBool
SizeTojsval(JSContext* cx, size_t size, jsval* result)
{
if (Convert<size_t>(jsdouble(size)) != size) {
if (Convert<size_t>(double(size)) != size) {
JS_ReportError(cx, "size overflow");
return false;
}
return JS_NewNumberValue(cx, jsdouble(size), result);
return JS_NewNumberValue(cx, double(size), result);
}
// Forcefully convert val to IntegerType when explicitly requested.
@ -1499,7 +1499,7 @@ jsvalToIntegerExplicit(jsval val, IntegerType* result)
if (JSVAL_IS_DOUBLE(val)) {
// Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
jsdouble d = JSVAL_TO_DOUBLE(val);
double d = JSVAL_TO_DOUBLE(val);
*result = FloatIsFinite(d) ? IntegerType(d) : 0;
return true;
}
@ -1532,11 +1532,11 @@ jsvalToPtrExplicit(JSContext* cx, jsval val, uintptr_t* result)
return true;
}
if (JSVAL_IS_DOUBLE(val)) {
jsdouble d = JSVAL_TO_DOUBLE(val);
double d = JSVAL_TO_DOUBLE(val);
if (d < 0) {
// Cast through an intptr_t intermediate to sign-extend.
intptr_t i = Convert<intptr_t>(d);
if (jsdouble(i) != d)
if (double(i) != d)
return false;
*result = uintptr_t(i);
@ -1546,7 +1546,7 @@ jsvalToPtrExplicit(JSContext* cx, jsval val, uintptr_t* result)
// Don't silently lose bits here -- check that val really is an
// integer value, and has the right sign.
*result = Convert<uintptr_t>(d);
return jsdouble(*result) == d;
return double(*result) == d;
}
if (!JSVAL_IS_PRIMITIVE(val)) {
JSObject* obj = JSVAL_TO_OBJECT(val);
@ -1651,7 +1651,7 @@ ConvertToJS(JSContext* cx,
type value = *static_cast<type*>(data); \
if (sizeof(type) < 4) \
*result = INT_TO_JSVAL(jsint(value)); \
else if (!JS_NewNumberValue(cx, jsdouble(value), result)) \
else if (!JS_NewNumberValue(cx, double(value), result)) \
return false; \
break; \
}
@ -1680,7 +1680,7 @@ ConvertToJS(JSContext* cx,
#define DEFINE_FLOAT_TYPE(name, type, ffiType) \
case TYPE_##name: { \
type value = *static_cast<type*>(data); \
if (!JS_NewNumberValue(cx, jsdouble(value), result)) \
if (!JS_NewNumberValue(cx, double(value), result)) \
return false; \
break; \
}
@ -2929,7 +2929,7 @@ CType::GetSafeSize(JSObject* obj, size_t* result)
jsval size = JS_GetReservedSlot(obj, SLOT_SIZE);
// The "size" property can be a jsint, a jsdouble, or JSVAL_VOID
// The "size" property can be a jsint, a double, or JSVAL_VOID
// (for arrays of undefined length), and must always fit in a size_t.
if (JSVAL_IS_INT(size)) {
*result = JSVAL_TO_INT(size);
@ -2953,7 +2953,7 @@ CType::GetSize(JSObject* obj)
JS_ASSERT(!JSVAL_IS_VOID(size));
// The "size" property can be a jsint, a jsdouble, or JSVAL_VOID
// The "size" property can be a jsint, a double, or JSVAL_VOID
// (for arrays of undefined length), and must always fit in a size_t.
// For callers who know it can never be JSVAL_VOID, return a size_t directly.
if (JSVAL_IS_INT(size))
@ -2968,7 +2968,7 @@ CType::IsSizeDefined(JSObject* obj)
jsval size = JS_GetReservedSlot(obj, SLOT_SIZE);
// The "size" property can be a jsint, a jsdouble, or JSVAL_VOID
// The "size" property can be a jsint, a double, or JSVAL_VOID
// (for arrays of undefined length), and must always fit in a size_t.
JS_ASSERT(JSVAL_IS_INT(size) || JSVAL_IS_DOUBLE(size) || JSVAL_IS_VOID(size));
return !JSVAL_IS_VOID(size);
@ -3599,7 +3599,7 @@ ArrayType::CreateInternal(JSContext* cx,
jsval sizeVal = JSVAL_VOID;
jsval lengthVal = JSVAL_VOID;
if (lengthDefined) {
// Check for overflow, and convert to a jsint or jsdouble as required.
// Check for overflow, and convert to a jsint or double as required.
size_t size = length * baseSize;
if (length > 0 && size / length != baseSize) {
JS_ReportError(cx, "size overflow");
@ -3750,7 +3750,7 @@ ArrayType::GetSafeLength(JSObject* obj, size_t* result)
jsval length = JS_GetReservedSlot(obj, SLOT_LENGTH);
// The "length" property can be a jsint, a jsdouble, or JSVAL_VOID
// The "length" property can be a jsint, a double, or JSVAL_VOID
// (for arrays of undefined length), and must always fit in a size_t.
if (JSVAL_IS_INT(length)) {
*result = JSVAL_TO_INT(length);
@ -3775,7 +3775,7 @@ ArrayType::GetLength(JSObject* obj)
JS_ASSERT(!JSVAL_IS_VOID(length));
// The "length" property can be a jsint, a jsdouble, or JSVAL_VOID
// The "length" property can be a jsint, a double, or JSVAL_VOID
// (for arrays of undefined length), and must always fit in a size_t.
// For callers who know it can never be JSVAL_VOID, return a size_t directly.
if (JSVAL_IS_INT(length))
@ -6207,7 +6207,7 @@ Int64::Lo(JSContext* cx, uintN argc, jsval* vp)
JSObject* obj = JSVAL_TO_OBJECT(argv[0]);
int64_t u = Int64Base::GetInt(obj);
jsdouble d = uint32_t(INT64_LO(u));
double d = uint32_t(INT64_LO(u));
jsval result;
if (!JS_NewNumberValue(cx, d, &result))
@ -6229,7 +6229,7 @@ Int64::Hi(JSContext* cx, uintN argc, jsval* vp)
JSObject* obj = JSVAL_TO_OBJECT(argv[0]);
int64_t u = Int64Base::GetInt(obj);
jsdouble d = int32_t(INT64_HI(u));
double d = int32_t(INT64_HI(u));
jsval result;
if (!JS_NewNumberValue(cx, d, &result))
@ -6374,7 +6374,7 @@ UInt64::Lo(JSContext* cx, uintN argc, jsval* vp)
JSObject* obj = JSVAL_TO_OBJECT(argv[0]);
uint64_t u = Int64Base::GetInt(obj);
jsdouble d = uint32_t(INT64_LO(u));
double d = uint32_t(INT64_LO(u));
jsval result;
if (!JS_NewNumberValue(cx, d, &result))
@ -6396,7 +6396,7 @@ UInt64::Hi(JSContext* cx, uintN argc, jsval* vp)
JSObject* obj = JSVAL_TO_OBJECT(argv[0]);
uint64_t u = Int64Base::GetInt(obj);
jsdouble d = uint32_t(INT64_HI(u));
double d = uint32_t(INT64_HI(u));
jsval result;
if (!JS_NewNumberValue(cx, d, &result))

View File

@ -92,9 +92,6 @@ static JSBool
NewTryNote(JSContext *cx, BytecodeEmitter *bce, JSTryNoteKind kind, uintN stackDepth,
size_t start, size_t end);
static bool
EmitIndexOp(JSContext *cx, JSOp op, uintN index, BytecodeEmitter *bce, JSOp *psuffix = NULL);
static JSBool
SetSrcNoteOffset(JSContext *cx, BytecodeEmitter *bce, uintN index, uintN which, ptrdiff_t offset);
@ -866,97 +863,44 @@ LookupCompileTimeConstant(JSContext *cx, BytecodeEmitter *bce, JSAtom *atom, Val
return JS_TRUE;
}
static inline bool
FitsWithoutBigIndex(uintN index)
{
return index < JS_BIT(16);
}
/*
* Return JSOP_NOP to indicate that index fits 2 bytes and no index segment
* reset instruction is necessary, JSOP_FALSE to indicate an error or either
* JSOP_RESETBASE0 or JSOP_RESETBASE1 to indicate the reset bytecode to issue
* after the main bytecode sequence.
*/
static JSOp
EmitBigIndexPrefix(JSContext *cx, BytecodeEmitter *bce, uintN index)
{
uintN indexBase;
/*
* We have max 3 bytes for indexes and check for INDEX_LIMIT overflow only
* for big indexes.
*/
JS_STATIC_ASSERT(INDEX_LIMIT <= JS_BIT(24));
JS_STATIC_ASSERT(INDEX_LIMIT >=
(JSOP_INDEXBASE3 - JSOP_INDEXBASE1 + 2) << 16);
if (FitsWithoutBigIndex(index))
return JSOP_NOP;
indexBase = index >> 16;
if (indexBase <= JSOP_INDEXBASE3 - JSOP_INDEXBASE1 + 1) {
if (Emit1(cx, bce, (JSOp)(JSOP_INDEXBASE1 + indexBase - 1)) < 0)
return JSOP_FALSE;
return JSOP_RESETBASE0;
}
if (index >= INDEX_LIMIT) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TOO_MANY_LITERALS);
return JSOP_FALSE;
}
if (Emit2(cx, bce, JSOP_INDEXBASE, (JSOp)indexBase) < 0)
return JSOP_FALSE;
return JSOP_RESETBASE;
}
/*
* Emit a bytecode and its 2-byte constant index immediate operand. If the
* index requires more than 2 bytes, emit a prefix op whose 8-bit immediate
* operand effectively extends the 16-bit immediate of the prefixed opcode,
* by changing index "segment" (see jsinterp.c). We optimize segments 1-3
* with single-byte JSOP_INDEXBASE[123] codes.
*
* Such prefixing currently requires a suffix to restore the "zero segment"
* register setting, but this could be optimized further.
*/
static bool
EmitIndexOp(JSContext *cx, JSOp op, uintN index, BytecodeEmitter *bce, JSOp *psuffix)
EmitIndex32(JSContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
{
JSOp bigSuffix;
bigSuffix = EmitBigIndexPrefix(cx, bce, index);
if (bigSuffix == JSOP_FALSE)
const size_t len = 1 + UINT32_INDEX_LEN;
JS_ASSERT(len == size_t(js_CodeSpec[op].length));
ptrdiff_t offset = EmitCheck(cx, bce, len);
if (offset < 0)
return false;
EMIT_UINT16_IMM_OP(op, index);
/*
* For decomposed ops, the suffix needs to go after the decomposed version.
* This means the suffix will run in the interpreter in both the base
* and decomposed paths, which works as suffix ops are idempotent.
*/
JS_ASSERT(!!(js_CodeSpec[op].format & JOF_DECOMPOSE) == (psuffix != NULL));
if (psuffix) {
*psuffix = bigSuffix;
return true;
}
return bigSuffix == JSOP_NOP || Emit1(cx, bce, bigSuffix) >= 0;
jsbytecode *next = bce->next();
next[0] = jsbytecode(op);
SET_UINT32_INDEX(next, index);
bce->current->next = next + len;
UpdateDepth(cx, bce, offset);
CheckTypeSet(cx, bce, op);
return true;
}
/*
* Slight sugar for EmitIndexOp, again accessing cx and bce from the macro
* caller's lexical environment, and embedding a false return on error.
*/
#define EMIT_INDEX_OP(op, index) \
JS_BEGIN_MACRO \
if (!EmitIndexOp(cx, op, index, bce)) \
return JS_FALSE; \
JS_END_MACRO
static bool
EmitIndexOp(JSContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
{
const size_t len = js_CodeSpec[op].length;
JS_ASSERT(len >= 1 + UINT32_INDEX_LEN);
ptrdiff_t offset = EmitCheck(cx, bce, len);
if (offset < 0)
return false;
jsbytecode *next = bce->next();
next[0] = jsbytecode(op);
SET_UINT32_INDEX(next, index);
bce->current->next = next + len;
UpdateDepth(cx, bce, offset);
CheckTypeSet(cx, bce, op);
return true;
}
static bool
EmitAtomOp(JSContext *cx, JSAtom *atom, JSOp op, BytecodeEmitter *bce, JSOp *psuffix = NULL)
EmitAtomOp(JSContext *cx, JSAtom *atom, JSOp op, BytecodeEmitter *bce)
{
JS_ASSERT(JOF_OPTYPE(op) == JOF_ATOM);
@ -969,20 +913,27 @@ EmitAtomOp(JSContext *cx, JSAtom *atom, JSOp op, BytecodeEmitter *bce, JSOp *psu
if (!bce->makeAtomIndex(atom, &index))
return false;
return EmitIndexOp(cx, op, index, bce, psuffix);
return EmitIndexOp(cx, op, index, bce);
}
static bool
EmitAtomOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce, JSOp *psuffix = NULL)
EmitAtomOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
{
JS_ASSERT(pn->pn_atom != NULL);
return EmitAtomOp(cx, pn->pn_atom, op, bce, psuffix);
return EmitAtomOp(cx, pn->pn_atom, op, bce);
}
static bool
EmitIndex32(JSContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
EmitAtomIncDec(JSContext *cx, JSAtom *atom, JSOp op, BytecodeEmitter *bce)
{
const size_t len = 1 + UINT32_INDEX_LEN;
JS_ASSERT(JOF_OPTYPE(op) == JOF_ATOM);
JS_ASSERT(js_CodeSpec[op].format & (JOF_INC | JOF_DEC));
jsatomid index;
if (!bce->makeAtomIndex(atom, &index))
return false;
const size_t len = 1 + UINT32_INDEX_LEN + 1;
JS_ASSERT(size_t(js_CodeSpec[op].length) == len);
ptrdiff_t offset = EmitCheck(cx, bce, len);
if (offset < 0)
@ -1026,7 +977,7 @@ EmitSlotObjectOp(JSContext *cx, JSOp op, uintN slot, uint32_t index, BytecodeEmi
return false;
jsbytecode *pc = bce->code(off);
SET_UINT16(pc, slot);
SET_SLOTNO(pc, slot);
pc += SLOTNO_LEN;
SET_UINT32_INDEX(pc, index);
return true;
@ -1887,6 +1838,7 @@ EmitNameOp(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, JSBool callContex
return JS_FALSE;
} else {
if (!pn->pn_cookie.isFree()) {
JS_ASSERT(JOF_OPTYPE(op) != JOF_ATOM);
EMIT_UINT16_IMM_OP(op, pn->pn_cookie.asInteger());
} else {
if (!EmitAtomOp(cx, pn, op, bce))
@ -1955,7 +1907,7 @@ EmitSpecialPropOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
jsatomid index;
if (!bce->makeAtomIndex(pn->pn_atom, &index))
return false;
if (!EmitIndexOp(cx, JSOP_QNAMEPART, index, bce))
if (!EmitIndex32(cx, JSOP_QNAMEPART, index, bce))
return false;
if (op == JSOP_CALLELEM && Emit1(cx, bce, JSOP_DUP) < 0)
@ -1972,7 +1924,7 @@ EmitSpecialPropOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
static bool
EmitPropOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce,
JSBool callContext, JSOp *psuffix = NULL)
JSBool callContext)
{
ParseNode *pn2, *pndot, *pnup, *pndown;
ptrdiff_t top;
@ -2053,7 +2005,7 @@ EmitPropOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce,
if (NewSrcNote2(cx, bce, SRC_PCBASE, bce->offset() - pn2->pn_offset) < 0)
return false;
if (!EmitAtomOp(cx, pn, op, bce, psuffix))
if (!EmitAtomOp(cx, pn, op, bce))
return false;
if (op == JSOP_CALLPROP && Emit1(cx, bce, JSOP_SWAP) < 0)
@ -2065,10 +2017,7 @@ EmitPropOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce,
static bool
EmitPropIncDec(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
{
JSOp suffix = JSOP_NOP;
if (!EmitPropOp(cx, pn, op, bce, false, &suffix))
return false;
if (Emit1(cx, bce, JSOP_NOP) < 0)
if (!EmitPropOp(cx, pn, op, bce, false))
return false;
/*
@ -2077,9 +2026,6 @@ EmitPropIncDec(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
*/
int start = bce->offset();
if (suffix != JSOP_NOP && Emit1(cx, bce, suffix) < 0)
return false;
const JSCodeSpec *cs = &js_CodeSpec[op];
JS_ASSERT(cs->format & JOF_PROP);
JS_ASSERT(cs->format & (JOF_INC | JOF_DEC));
@ -2115,19 +2061,14 @@ EmitPropIncDec(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
UpdateDecomposeLength(bce, start);
if (suffix != JSOP_NOP && Emit1(cx, bce, suffix) < 0)
return false;
return true;
}
static bool
EmitNameIncDec(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
{
JSOp suffix = JSOP_NOP;
if (!EmitAtomOp(cx, pn, op, bce, &suffix))
return false;
if (Emit1(cx, bce, JSOP_NOP) < 0)
/* Emit the composite op, including the slack byte at the end. */
if (!EmitAtomIncDec(cx, pn->pn_atom, op, bce))
return false;
/* Remove the result to restore the stack depth before the INCNAME. */
@ -2135,9 +2076,6 @@ EmitNameIncDec(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
int start = bce->offset();
if (suffix != JSOP_NOP && Emit1(cx, bce, suffix) < 0)
return false;
const JSCodeSpec *cs = &js_CodeSpec[op];
JS_ASSERT((cs->format & JOF_NAME) || (cs->format & JOF_GNAME));
JS_ASSERT(cs->format & (JOF_INC | JOF_DEC));
@ -2173,9 +2111,6 @@ EmitNameIncDec(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
UpdateDecomposeLength(bce, start);
if (suffix != JSOP_NOP && Emit1(cx, bce, suffix) < 0)
return false;
return true;
}
@ -2301,7 +2236,7 @@ EmitElemIncDec(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
}
static JSBool
EmitNumberOp(JSContext *cx, jsdouble dval, BytecodeEmitter *bce)
EmitNumberOp(JSContext *cx, double dval, BytecodeEmitter *bce)
{
int32_t ival;
uint32_t u;
@ -2338,7 +2273,7 @@ EmitNumberOp(JSContext *cx, jsdouble dval, BytecodeEmitter *bce)
if (!bce->constList.append(DoubleValue(dval)))
return JS_FALSE;
return EmitIndexOp(cx, JSOP_DOUBLE, bce->constList.length() - 1, bce);
return EmitIndex32(cx, JSOP_DOUBLE, bce->constList.length() - 1, bce);
}
/*
@ -2612,8 +2547,8 @@ EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* 1 offset (len) and 1 atom index (npairs) before the table,
* 1 atom index and 1 jump offset per entry.
*/
switchSize = (size_t)(JUMP_OFFSET_LEN + INDEX_LEN +
(INDEX_LEN + JUMP_OFFSET_LEN) * caseCount);
switchSize = (size_t)(JUMP_OFFSET_LEN + UINT16_LEN +
(UINT32_INDEX_LEN + JUMP_OFFSET_LEN) * caseCount);
}
/* Emit switchOp followed by switchSize bytes of jump or lookup table. */
@ -2711,8 +2646,8 @@ EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
JS_ASSERT(switchOp == JSOP_LOOKUPSWITCH);
/* Fill in the number of cases. */
SET_INDEX(pc, caseCount);
pc += INDEX_LEN;
SET_UINT16(pc, caseCount);
pc += UINT16_LEN;
}
/*
@ -2761,7 +2696,7 @@ EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (NewSrcNote2(cx, bce, SRC_LABEL, ptrdiff_t(index)) < 0)
goto bad;
}
pc += INDEX_LEN + JUMP_OFFSET_LEN;
pc += UINT32_INDEX_LEN + JUMP_OFFSET_LEN;
}
}
bce->current->next = savepc;
@ -2819,15 +2754,15 @@ EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
}
} else if (switchOp == JSOP_LOOKUPSWITCH) {
/* Skip over the already-initialized number of cases. */
pc += INDEX_LEN;
pc += UINT16_LEN;
for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
if (pn3->isKind(PNK_DEFAULT))
continue;
if (!bce->constList.append(*pn3->pn_pval))
goto bad;
SET_INDEX(pc, bce->constList.length() - 1);
pc += INDEX_LEN;
SET_UINT32_INDEX(pc, bce->constList.length() - 1);
pc += UINT32_INDEX_LEN;
off = pn3->pn_offset - top;
SET_JUMP_OFFSET(pc, off);
@ -2911,7 +2846,8 @@ MaybeEmitVarDecl(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *
bce->switchToProlog();
if (!UpdateLineNumberNotes(cx, bce, pn->pn_pos.begin.lineno))
return false;
EMIT_INDEX_OP(prologOp, atomIndex);
if (!EmitIndexOp(cx, prologOp, atomIndex, bce))
return false;
bce->switchToMain();
}
@ -3613,10 +3549,11 @@ EmitVariables(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption
if (pn3) {
JS_ASSERT(emitOption != DefineVars);
JS_ASSERT_IF(emitOption == PushInitialValues, op == JSOP_SETLOCAL);
if (op == JSOP_SETNAME)
EMIT_INDEX_OP(JSOP_BINDNAME, atomIndex);
else if (op == JSOP_SETGNAME)
EMIT_INDEX_OP(JSOP_BINDGNAME, atomIndex);
if (op == JSOP_SETNAME || op == JSOP_SETGNAME) {
JSOp bindOp = (op == JSOP_SETNAME) ? JSOP_BINDNAME : JSOP_BINDGNAME;
if (!EmitIndex32(cx, bindOp, atomIndex, bce))
return false;
}
if (pn->isOp(JSOP_DEFCONST) &&
!DefineCompileTimeConstant(cx, bce, pn2->pn_atom, pn3))
{
@ -3657,7 +3594,8 @@ EmitVariables(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption
} else if (!pn2->pn_cookie.isFree()) {
EMIT_UINT16_IMM_OP(op, atomIndex);
} else {
EMIT_INDEX_OP(op, atomIndex);
if (!EmitIndexOp(cx, op, atomIndex, bce))
return false;
}
#if JS_HAS_DESTRUCTURING
@ -3708,7 +3646,8 @@ EmitAssignment(JSContext *cx, BytecodeEmitter *bce, ParseNode *lhs, JSOp op, Par
return false;
if (!lhs->isConst()) {
JSOp op = lhs->isOp(JSOP_SETGNAME) ? JSOP_BINDGNAME : JSOP_BINDNAME;
EMIT_INDEX_OP(op, atomIndex);
if (!EmitIndex32(cx, op, atomIndex, bce))
return false;
offset++;
}
}
@ -3761,17 +3700,23 @@ EmitAssignment(JSContext *cx, BytecodeEmitter *bce, ParseNode *lhs, JSOp op, Par
if (lhs->isOp(JSOP_CALLEE)) {
if (Emit1(cx, bce, JSOP_CALLEE) < 0)
return false;
} else if (lhs->isOp(JSOP_NAME)) {
if (!EmitIndex32(cx, lhs->getOp(), atomIndex, bce))
return false;
} else {
EMIT_INDEX_OP(lhs->getOp(), atomIndex);
JS_ASSERT(JOF_OPTYPE(lhs->getOp()) != JOF_ATOM);
EMIT_UINT16_IMM_OP(lhs->getOp(), atomIndex);
}
} else if (lhs->isOp(JSOP_SETNAME)) {
if (Emit1(cx, bce, JSOP_DUP) < 0)
return false;
EMIT_INDEX_OP(JSOP_GETXPROP, atomIndex);
if (!EmitIndex32(cx, JSOP_GETXPROP, atomIndex, bce))
return false;
} else if (lhs->isOp(JSOP_SETGNAME)) {
if (!BindGlobal(cx, bce, lhs, lhs->pn_atom))
return false;
EmitAtomOp(cx, lhs, JSOP_GETGNAME, bce);
if (!EmitAtomOp(cx, lhs, JSOP_GETGNAME, bce))
return false;
} else {
EMIT_UINT16_IMM_OP(lhs->isOp(JSOP_SETARG) ? JSOP_GETARG : JSOP_GETLOCAL, atomIndex);
}
@ -3780,13 +3725,14 @@ EmitAssignment(JSContext *cx, BytecodeEmitter *bce, ParseNode *lhs, JSOp op, Par
if (Emit1(cx, bce, JSOP_DUP) < 0)
return false;
if (lhs->pn_atom == cx->runtime->atomState.protoAtom) {
if (!EmitIndexOp(cx, JSOP_QNAMEPART, atomIndex, bce))
if (!EmitIndex32(cx, JSOP_QNAMEPART, atomIndex, bce))
return false;
if (!EmitElemOpBase(cx, bce, JSOP_GETELEM))
return false;
} else {
bool isLength = (lhs->pn_atom == cx->runtime->atomState.lengthAtom);
EMIT_INDEX_OP(isLength ? JSOP_LENGTH : JSOP_GETPROP, atomIndex);
if (!EmitIndex32(cx, isLength ? JSOP_LENGTH : JSOP_GETPROP, atomIndex, bce))
return false;
}
break;
case PNK_LB:
@ -3850,9 +3796,17 @@ EmitAssignment(JSContext *cx, BytecodeEmitter *bce, ParseNode *lhs, JSOp op, Par
}
break;
}
/* FALL THROUGH */
if (lhs->isOp(JSOP_SETARG) || lhs->isOp(JSOP_SETLOCAL)) {
JS_ASSERT(atomIndex < UINT16_MAX);
EMIT_UINT16_IMM_OP(lhs->getOp(), atomIndex);
} else {
if (!EmitIndexOp(cx, lhs->getOp(), atomIndex, bce))
return false;
}
break;
case PNK_DOT:
EMIT_INDEX_OP(lhs->getOp(), atomIndex);
if (!EmitIndexOp(cx, lhs->getOp(), atomIndex, bce))
return false;
break;
case PNK_LB:
case PNK_LP:
@ -4562,7 +4516,8 @@ EmitXMLTag(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
: cx->runtime->atomState.stagoAtom;
if (!bce->makeAtomIndex(tagAtom, &index))
return false;
EMIT_INDEX_OP(JSOP_STRING, index);
if (!EmitIndex32(cx, JSOP_STRING, index, bce))
return false;
}
JS_ASSERT(pn->pn_count != 0);
@ -4594,7 +4549,8 @@ EmitXMLTag(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
: cx->runtime->atomState.tagcAtom;
if (!bce->makeAtomIndex(tmp, &index))
return false;
EMIT_INDEX_OP(JSOP_STRING, index);
if (!EmitIndex32(cx, JSOP_STRING, index, bce))
return false;
}
if (Emit1(cx, bce, JSOP_ADD) < 0)
return false;
@ -4613,7 +4569,7 @@ EmitXMLProcessingInstruction(JSContext *cx, BytecodeEmitter *bce, XMLProcessingI
jsatomid index;
if (!bce->makeAtomIndex(pi.data(), &index))
return false;
if (!EmitIndexOp(cx, JSOP_QNAMEPART, index, bce))
if (!EmitIndex32(cx, JSOP_QNAMEPART, index, bce))
return false;
if (!EmitAtomOp(cx, pi.target(), JSOP_XMLPI, bce))
return false;
@ -6042,7 +5998,8 @@ EmitObject(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
obj = NULL;
}
EMIT_INDEX_OP(op, index);
if (!EmitIndex32(cx, op, index, bce))
return false;
}
}
@ -6051,18 +6008,16 @@ EmitObject(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (obj) {
/*
* The object survived and has a predictable shape. Update the original bytecode,
* as long as we can do so without using a big index prefix/suffix.
* The object survived and has a predictable shape: update the original
* bytecode.
*/
ObjectBox *objbox = bce->parser->newObjectBox(obj);
if (!objbox)
return false;
uintN index = bce->objectList.index(objbox);
if (FitsWithoutBigIndex(index)) {
MOZ_STATIC_ASSERT(JSOP_NEWINIT_LENGTH == JSOP_NEWOBJECT_LENGTH,
"newinit and newobject must have equal length to edit in-place");
EMIT_UINT32_IN_PLACE(offset, JSOP_NEWOBJECT, uint32_t(index));
}
MOZ_STATIC_ASSERT(JSOP_NEWINIT_LENGTH == JSOP_NEWOBJECT_LENGTH,
"newinit and newobject must have equal length to edit in-place");
EMIT_UINT32_IN_PLACE(offset, JSOP_NEWOBJECT, uint32_t(index));
}
return true;
@ -6644,7 +6599,8 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
jsatomid index;
if (!bce->makeAtomIndex(atom, &index))
return JS_FALSE;
EMIT_INDEX_OP(JSOP_STRING, index);
if (!EmitIndex32(cx, JSOP_STRING, index, bce))
return false;
}
if (Emit1(cx, bce, pn->getOp()) < 0)
return JS_FALSE;

View File

@ -109,7 +109,7 @@ FoldType(JSContext *cx, ParseNode *pn, ParseNodeKind kind)
switch (kind) {
case PNK_NUMBER:
if (pn->isKind(PNK_STRING)) {
jsdouble d;
double d;
if (!ToNumber(cx, StringValue(pn->pn_atom), &d))
return JS_FALSE;
pn->pn_dval = d;
@ -146,7 +146,7 @@ static JSBool
FoldBinaryNumeric(JSContext *cx, JSOp op, ParseNode *pn1, ParseNode *pn2,
ParseNode *pn, TreeContext *tc)
{
jsdouble d, d2;
double d, d2;
int32_t i, j;
JS_ASSERT(pn1->isKind(PNK_NUMBER) && pn2->isKind(PNK_NUMBER));
@ -822,7 +822,7 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
case PNK_POS:
case PNK_NEG:
if (pn1->isKind(PNK_NUMBER)) {
jsdouble d;
double d;
/* Operate on one numeric constant. */
d = pn1->pn_dval;

View File

@ -619,7 +619,7 @@ struct ParseNode {
AtomDefnMapPtr defnMap;
ParseNode *tree; /* sub-tree containing name uses */
} nameset;
jsdouble dval; /* aligned numeric literal value */
double dval; /* aligned numeric literal value */
class {
friend class LoopControlStatement;
PropertyName *label; /* target of break/continue statement */

View File

@ -1732,7 +1732,7 @@ TokenStream::getTokenInternal()
* chars, so we don't need to use tokenbuf. Instead we can just
* convert the jschars in userbuf directly to the numeric value.
*/
jsdouble dval;
double dval;
const jschar *dummy;
if (!hasFracOrExp) {
if (!GetPrefixInteger(cx, numStart, userbuf.addressOfNextRawChar(), 10, &dummy, &dval))
@ -1823,7 +1823,7 @@ TokenStream::getTokenInternal()
goto error;
}
jsdouble dval;
double dval;
const jschar *dummy;
if (!GetPrefixInteger(cx, numStart, userbuf.addressOfNextRawChar(), radix, &dummy, &dval))
goto error;

View File

@ -322,7 +322,7 @@ struct Token {
PropertyName *target; /* non-empty */
JSAtom *data; /* maybe empty, never null */
} xmlpi;
jsdouble number; /* floating point number */
double number; /* floating point number */
RegExpFlag reflags; /* regexp flags, use tokenbuf to access
regexp chars */
} u;
@ -359,7 +359,7 @@ struct Token {
u.reflags = flags;
}
void setNumber(jsdouble n) {
void setNumber(double n) {
u.number = n;
}
@ -396,7 +396,7 @@ struct Token {
return u.reflags;
}
jsdouble number() const {
double number() const {
JS_ASSERT(type == TOK_NUMBER);
return u.number;
}

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