Merge last green PGO from inbound to central
@ -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
|
||||
|
@ -136,7 +136,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
"combobox",
|
||||
roles::COMBOBOX,
|
||||
kUseMapRole,
|
||||
eHasValueMinMax,
|
||||
eNoValue,
|
||||
eOpenCloseAction,
|
||||
eNoLiveAttr,
|
||||
states::COLLAPSED | states::HASPOPUP,
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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 \
|
||||
|
29
browser/base/content/test/browser_urlbarRevert.js
Normal 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);
|
||||
});
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
},
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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() {},
|
||||
|
@ -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() {},
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
});
|
||||
|
||||
|
@ -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;
|
||||
},
|
||||
|
@ -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] {
|
||||
|
Before Width: | Height: | Size: 732 B After Width: | Height: | Size: 3.8 KiB |
@ -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) {
|
||||
|
@ -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],
|
||||
|
@ -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)
|
||||
|
Before Width: | Height: | Size: 634 B |
BIN
browser/themes/pinstripe/places/livemark-item.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
@ -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),
|
||||
|
@ -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] {
|
||||
|
@ -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)
|
||||
|
Before Width: | Height: | Size: 555 B |
Before Width: | Height: | Size: 640 B |
BIN
browser/themes/winstripe/places/livemark-item.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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 \
|
||||
|
2
content/base/test/eventsource_redirect.resource
Normal file
@ -0,0 +1,2 @@
|
||||
redirected
|
||||
|
3
content/base/test/eventsource_redirect.resource^headers^
Normal file
@ -0,0 +1,3 @@
|
||||
HTTP 301 Moved Permanently
|
||||
Location: eventsource_redirect_to.resource
|
||||
|
3
content/base/test/eventsource_redirect_to.resource
Normal file
@ -0,0 +1,3 @@
|
||||
retry:500
|
||||
data: 1
|
||||
|
@ -0,0 +1,3 @@
|
||||
Content-Type: text/event-stream
|
||||
Cache-Control: no-cache, must-revalidate
|
||||
|
59
content/base/test/test_EventSource_redirects.html
Normal 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>
|
||||
|
@ -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) ||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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>
|
@ -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>
|
||||
|
@ -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*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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!");
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
||||
|
34
gfx/angle/angle-enforce-readpixels-spec.patch
Normal 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;
|
||||
}
|
71
gfx/angle/angle-impl-read-bgra.patch
Normal 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
|
@ -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) |
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
26
js/jsd/jsd.h
@ -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*
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -154,6 +154,7 @@ CPPSRCS = \
|
||||
Debugger.cpp \
|
||||
GlobalObject.cpp \
|
||||
MethodGuard.cpp \
|
||||
ObjectImpl.cpp \
|
||||
Stack.cpp \
|
||||
String.cpp \
|
||||
BytecodeCompiler.cpp \
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|