Merge mozilla-central to mozilla-inbound

This commit is contained in:
Ed Morley 2012-07-24 14:39:34 +01:00
Родитель 1f2416e756 0095f01ad0
Коммит 921626e7e1
50 изменённых файлов: 878 добавлений и 172 удалений

Просмотреть файл

@ -1186,3 +1186,5 @@ pref("image.mem.max_decoded_image_kb", 256000);
// Example social provider
pref("social.manifest.motown", "{\"origin\":\"https://motown-dev.mozillalabs.com\",\"name\":\"MoTown\",\"workerURL\":\"https://motown-dev.mozillalabs.com/social/worker.js\",\"iconURL\":\"https://motown-dev.mozillalabs.com/images/motown-icon.png\",\"sidebarURL\":\"https://motown-dev.mozillalabs.com/social/sidebar\"}");
pref("social.sidebar.open", true);
pref("browser.social.whitelist", "");
pref("social.active", false);

Просмотреть файл

@ -332,6 +332,10 @@
label="&preferencesCmd2.label;"
#endif
oncommand="openPreferences();">
<menuitem id="appmenu_socialToggle"
type="checkbox"
autocheck="false"
command="Social:Toggle"/>
<menupopup id="appmenu_customizeMenu"
onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleToolbarsSeparator'));">
<menuitem id="appmenu_preferences"

Просмотреть файл

@ -496,6 +496,10 @@
accesskey="&addons.accesskey;"
key="key_openAddons"
command="Tools:Addons"/>
<menuitem id="menu_socialToggle"
type="checkbox"
autocheck="false"
command="Social:Toggle"/>
#ifdef MOZ_SERVICES_SYNC
<!-- only one of sync-setup or sync-menu will be showing at once -->
<menuitem id="sync-setup"

Просмотреть файл

@ -108,6 +108,7 @@
<command id="Social:SharePage" oncommand="SocialShareButton.sharePage();"/>
<command id="Social:UnsharePage" oncommand="SocialShareButton.unsharePage();"/>
<command id="Social:ToggleSidebar" oncommand="Social.toggleSidebar();"/>
<command id="Social:Toggle" oncommand="Social.toggle();" hidden="true"/>
</commandset>
<commandset id="placesCommands">

Просмотреть файл

@ -11,6 +11,8 @@ let SocialUI = {
Services.prefs.addObserver("social.sidebar.open", this, false);
gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler, true, true);
Social.init(this._providerReady.bind(this));
},
@ -31,6 +33,7 @@ let SocialUI = {
observe: function SocialUI_observe(subject, topic, data) {
switch (topic) {
case "social:pref-changed":
this.updateToggleCommand();
SocialShareButton.updateButtonHiddenState();
SocialToolbar.updateButtonHiddenState();
SocialSidebar.updateSidebar();
@ -46,11 +49,103 @@ let SocialUI = {
}
},
get toggleCommand() {
return document.getElementById("Social:Toggle");
},
// Called once Social.jsm's provider has been set
_providerReady: function SocialUI_providerReady() {
// If we couldn't find a provider, nothing to do here.
if (!Social.provider)
return;
this.updateToggleCommand();
let toggleCommand = this.toggleCommand;
let label = gNavigatorBundle.getFormattedString("social.enable.label",
[Social.provider.name]);
let accesskey = gNavigatorBundle.getString("social.enable.accesskey");
toggleCommand.setAttribute("label", label);
toggleCommand.setAttribute("accesskey", accesskey);
SocialToolbar.init();
SocialShareButton.init();
SocialSidebar.init();
},
updateToggleCommand: function SocialUI_updateToggleCommand() {
let toggleCommand = this.toggleCommand;
toggleCommand.setAttribute("checked", Social.enabled);
// FIXME: bug 772808: menu items don't inherit the "hidden" state properly,
// need to update them manually.
// This should just be: toggleCommand.hidden = !Social.active;
for (let id of ["appmenu_socialToggle", "menu_socialToggle"]) {
let el = document.getElementById(id);
if (!el)
continue;
if (Social.active)
el.removeAttribute("hidden");
else
el.setAttribute("hidden", "true");
}
},
// This handles "ActivateSocialFeature" events fired against content documents
// in this window.
_activationEventHandler: function SocialUI_activationHandler(e) {
// Nothing to do if Social is already active, or we don't have a provider
// to enable yet.
if (Social.active || !Social.provider)
return;
let targetDoc = e.target;
// Event must be fired against the document
if (!(targetDoc instanceof HTMLDocument))
return;
// Ignore events fired in background tabs
if (targetDoc.defaultView.top != content)
return;
// Check that the associated document's origin is in our whitelist
let prePath = targetDoc.documentURIObject.prePath;
let whitelist = Services.prefs.getCharPref("browser.social.whitelist");
if (whitelist.split(",").indexOf(prePath) == -1)
return;
// If the last event was received < 1s ago, ignore this one
let now = Date.now();
if (now - Social.lastEventReceived < 1000)
return;
Social.lastEventReceived = now;
// Enable the social functionality, and indicate that it was activated
Social.active = true;
// Show a warning, allow undoing the activation
let description = document.getElementById("social-activation-message");
let brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
let message = gNavigatorBundle.getFormattedString("social.activated.message",
[Social.provider.name, brandShortName]);
description.value = message;
SocialUI.notificationPanel.hidden = false;
setTimeout(function () {
SocialUI.notificationPanel.openPopup(SocialToolbar.button, "bottomcenter topright");
}.bind(this), 0);
},
get notificationPanel() {
return document.getElementById("socialActivatedNotification")
},
undoActivation: function SocialUI_undoActivation() {
Social.active = false;
this.notificationPanel.hidePopup();
}
}
@ -153,22 +248,33 @@ var SocialToolbar = {
// Called once, after window load, when the Social.provider object is initialized
init: function SocialToolbar_init() {
document.getElementById("social-provider-image").setAttribute("image", Social.provider.iconURL);
// handle button state
document.getElementById("social-statusarea-popup").addEventListener("popupshowing", function(e) {
document.getElementById("social-toolbar-button").setAttribute("open", "true");
}, false);
document.getElementById("social-statusarea-popup").addEventListener("popuphiding", function(e) {
document.getElementById("social-toolbar-button").removeAttribute("open");
}, false);
let removeItem = document.getElementById("social-remove-menuitem");
let brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
let label = gNavigatorBundle.getFormattedString("social.remove.label",
[brandShortName]);
let accesskey = gNavigatorBundle.getString("social.remove.accesskey");
removeItem.setAttribute("label", label);
removeItem.setAttribute("accesskey", accesskey);
let statusAreaPopup = document.getElementById("social-statusarea-popup");
statusAreaPopup.addEventListener("popupshowing", function(e) {
this.button.setAttribute("open", "true");
}.bind(this));
statusAreaPopup.addEventListener("popuphidden", function(e) {
this.button.removeAttribute("open");
}.bind(this));
this.updateButton();
this.updateProfile();
},
get button() {
return document.getElementById("social-toolbar-button");
},
updateButtonHiddenState: function SocialToolbar_updateButtonHiddenState() {
let toolbarbutton = document.getElementById("social-toolbar-button");
toolbarbutton.hidden = !Social.uiVisible;
this.button.hidden = !Social.uiVisible;
},
updateProfile: function SocialToolbar_updateProfile() {
@ -233,10 +339,10 @@ var SocialToolbar = {
panel.hidden = false;
function sizePanelToContent() {
// XXX Maybe we can use nsIDOMWindowUtils.getRootBounds() here?
// XXX need to handle dynamic sizing
// FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here?
// Need to handle dynamic sizing
let doc = notifBrowser.contentDocument;
// XXX "notif" is an implementation detail that we should get rid of
// "notif" is an implementation detail that we should get rid of
// eventually
let body = doc.getElementById("notif") || doc.body.firstChild;
if (!body)
@ -254,13 +360,13 @@ var SocialToolbar = {
panel.addEventListener("popuphiding", function onpopuphiding() {
panel.removeEventListener("popuphiding", onpopuphiding);
// unload the panel
document.getElementById("social-toolbar-button").removeAttribute("open");
SocialToolbar.button.removeAttribute("open");
notifBrowser.setAttribute("src", "about:blank");
});
notifBrowser.setAttribute("origin", Social.provider.origin);
notifBrowser.setAttribute("src", iconImage.getAttribute("contentPanel"));
document.getElementById("social-toolbar-button").setAttribute("open", "true");
this.button.setAttribute("open", "true");
panel.openPopup(iconImage, "bottomcenter topleft", 0, 0, false, false);
}
}

Просмотреть файл

@ -182,6 +182,44 @@
</hbox>
</panel>
<panel id="socialActivatedNotification"
type="arrow"
hidden="true"
consumeoutsideclicks="true"
align="start"
role="alert">
<hbox flex="1">
<image src="chrome://browser/content/social-icon.png" class="popup-notification-icon"/>
<vbox flex="1">
<description id="social-activation-message" class="popup-notification-description"/>
<spacer flex="1"/>
<hbox pack="end" align="center" class="popup-notification-button-container">
#ifdef XP_UNIX
<button id="social-undoactivation-button"
label="&social.activated.button.label;"
accesskey="&social.activated.button.accesskey;"
onclick="SocialUI.undoActivation();"/>
<button default="true"
autofocus="autofocus"
label="&social.ok.label;"
accesskey="&social.ok.accesskey;"
oncommand="SocialUI.notificationPanel.hidePopup();"/>
#else
<button default="true"
autofocus="autofocus"
label="&social.ok.label;"
accesskey="&social.ok.accesskey;"
oncommand="SocialUI.notificationPanel.hidePopup();"/>
<button id="social-undoactivation-button"
label="&social.activated.button.label;"
accesskey="&social.activated.button.accesskey;"
onclick="SocialUI.undoActivation();"/>
#endif
</hbox>
</vbox>
</hbox>
</panel>
<panel id="editSharePopup"
type="arrow"
orient="vertical"
@ -214,16 +252,16 @@
class="editSharePopupBottomButton"
default="true"
autofocus="autofocus"
label="&social.sharePopup.ok.label;"
accesskey="&social.sharePopup.ok.accesskey;"
label="&social.ok.label;"
accesskey="&social.ok.accesskey;"
oncommand="SocialShareButton.dismissSharePopup();"/>
#else
<button id="editSharePopupOkButton"
class="editSharePopupBottomButton"
default="true"
autofocus="autofocus"
label="&social.sharePopup.ok.label;"
accesskey="&social.sharePopup.ok.accesskey;"
label="&social.ok.label;"
accesskey="&social.ok.accesskey;"
oncommand="SocialShareButton.dismissSharePopup();"/>
<button id="editSharePopupUndoButton"
class="editSharePopupBottomButton"
@ -638,6 +676,8 @@
oncommand="SocialUI.showProfile(); document.getElementById('social-statusarea-popup').hidePopup();"/>
</vbox>
</hbox>
<menuitem id="social-remove-menuitem"
oncommand="Social.active = false;"/>
<menuitem id="social-toggle-sidebar-menuitem"
type="checkbox"
autocheck="false"

Двоичные данные
browser/base/content/social-icon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.1 KiB

Просмотреть файл

@ -258,6 +258,10 @@ _BROWSER_FILES = \
browser_bug734076.js \
browser_social_toolbar.js \
browser_social_sidebar.js \
browser_social_mozSocial_API.js \
social_panel.html \
social_sidebar.html \
social_worker.js \
$(NULL)
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))

Просмотреть файл

@ -0,0 +1,87 @@
/* 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/. */
let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
function test() {
// XXX Bug 775779
if (Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2).isDebugBuild) {
ok(true, "can't run social sidebar test in debug builds because they falsely report leaks");
return;
}
waitForExplicitFinish();
let manifest = { // normal provider
name: "provider 1",
origin: "http://example.com",
sidebarURL: "http://example.com/browser/browser/base/content/test/social_sidebar.html",
workerURL: "http://example.com/browser/browser/base/content/test/social_worker.js",
iconURL: "chrome://branding/content/icon48.png"
};
runSocialTestWithProvider(manifest, doTest);
}
function doTest() {
let iconsReady = false;
let gotSidebarMessage = false;
function checkNext() {
if (iconsReady && gotSidebarMessage)
triggerIconPanel();
}
function triggerIconPanel() {
let statusIcons = document.getElementById("social-status-iconbox");
ok(!statusIcons.firstChild.collapsed, "status icon is visible");
// Click the button to trigger its contentPanel
let panel = document.getElementById("social-notification-panel");
EventUtils.synthesizeMouseAtCenter(statusIcons.firstChild, {});
}
let port = Social.provider.port;
ok(port, "provider has a port");
port.postMessage({topic: "test-init"});
Social.provider.port.onmessage = function (e) {
let topic = e.data.topic;
switch (topic) {
case "got-panel-message":
ok(true, "got panel message");
// Wait for the panel to close before ending the test
let panel = document.getElementById("social-notification-panel");
panel.addEventListener("popuphidden", function hiddenListener() {
panel.removeEventListener("popuphidden", hiddenListener);
SocialService.removeProvider(Social.provider.origin, finish);
});
panel.hidePopup();
break;
case "got-sidebar-message":
// The sidebar message will always come first, since it loads by default
ok(true, "got sidebar message");
info(topic);
gotSidebarMessage = true;
checkNext();
break;
}
}
// Our worker sets up ambient notification at the same time as it responds to
// the workerAPI initialization. If it's already initialized, we can
// immediately check the icons, otherwise wait for initialization by
// observing the topic sent out by the social service.
if (Social.provider.workerAPI.initialized) {
iconsReady = true;
checkNext();
} else {
Services.obs.addObserver(function obs() {
Services.obs.removeObserver(obs, "social:ambient-notification-changed");
// Let the other observers (like the one that updates the UI) run before
// checking the icons.
executeSoon(function () {
iconsReady = true;
checkNext();
});
}, "social:ambient-notification-changed", false);
}
}

Просмотреть файл

@ -0,0 +1,14 @@
<html>
<head>
<meta charset="utf-8">
<script>
function pingWorker() {
var port = navigator.mozSocial.getWorker().port;
port.postMessage({topic: "panel-message", result: "ok"});
}
</script>
</head>
<body onload="pingWorker();">
<p>This is a test social panel.</p>
</body>
</html>

Просмотреть файл

@ -0,0 +1,14 @@
<html>
<head>
<meta charset="utf-8">
<script>
function pingWorker() {
var port = navigator.mozSocial.getWorker().port;
port.postMessage({topic: "sidebar-message", result: "ok"});
}
</script>
</head>
<body onload="pingWorker();">
<p>This is a test social sidebar.</p>
</body>
</html>

Просмотреть файл

@ -0,0 +1,40 @@
/* 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/. */
let testPort;
onconnect = function(e) {
let port = e.ports[0];
port.onmessage = function onMessage(event) {
let topic = event.data.topic;
switch (topic) {
case "test-init":
testPort = port;
break;
case "sidebar-message":
if (testPort && event.data.result == "ok")
testPort.postMessage({topic:"got-sidebar-message"});
break;
case "panel-message":
if (testPort && event.data.result == "ok")
testPort.postMessage({topic:"got-panel-message"});
break;
case "social.initialize":
// This is the workerAPI port, respond and set up a notification icon.
port.postMessage({topic: "social.initialize-response"});
let profile = {
userName: "foo"
};
port.postMessage({topic: "social.user-profile", data: profile});
let icon = {
name: "testIcon",
iconURL: "chrome://branding/content/icon48.png",
contentPanel: "http://example.com/browser/browser/base/content/test/social_panel.html",
counter: 1
};
port.postMessage({topic: "social.ambient-notification", data: icon});
break;
}
}
}

Просмотреть файл

@ -101,6 +101,7 @@ browser.jar:
#ifdef XP_WIN
* content/browser/win6BrowserOverlay.xul (content/win6BrowserOverlay.xul)
#endif
content/browser/social-icon.png (content/social-icon.png)
# the following files are browser-specific overrides
* content/browser/license.html (/toolkit/content/license.html)
% override chrome://global/content/license.html chrome://browser/content/license.html

Просмотреть файл

@ -657,11 +657,21 @@ toolbar button -->
<!ENTITY socialToolbar.title "Social Toolbar Button">
<!ENTITY social.notLoggedIn.label "Not logged in">
<!-- LOCALIZATION NOTE (social.ok.label, social.ok.accesskey): this string is
used for the "OK" button for two different social panels. One appears when
the feature is activated (social.activated.* below), and the other when
the user clicks the "Share" button a second time (social.sharePopup.*
below). -->
<!ENTITY social.ok.label "OK">
<!ENTITY social.ok.accesskey "O">
<!ENTITY social.sharePopup.undo.label "Unshare">
<!ENTITY social.sharePopup.undo.accesskey "U">
<!ENTITY social.sharePopup.ok.label "OK">
<!ENTITY social.sharePopup.ok.accesskey "O">
<!ENTITY social.sharePopup.shared.label "You shared this page.">
<!ENTITY social.sharePopup.portrait.arialabel "User profile picture">
<!ENTITY social.toggleSidebar.label "Show sidebar">
<!ENTITY social.toggleSidebar.accesskey "s">
<!ENTITY social.activated.button.label "Oops, undo">
<!ENTITY social.activated.button.accesskey "u">

Просмотреть файл

@ -372,3 +372,14 @@ fullscreen.rememberDecision=Remember decision for %S
social.shareButton.tooltip=Share this
social.shareButton.sharedtooltip=You shared this
social.pageShared.label=Page shared
# LOCALIZATION NOTE (social.enable.label): %S = Social networking provider
social.enable.label=%S integration
social.enable.accesskey=n
# LOCALIZATION NOTE (social.remove.label): %S = brandShortName
social.remove.label=Remove from %S
social.remove.accesskey=R
# LOCALIZATION NOTE (social.enabled.message): %1$S is the name of the social provider, %2$S is brandShortName (e.g. Firefox)
social.activated.message=%1$S integration with %2$S has been activated.

Просмотреть файл

@ -17,6 +17,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "SocialService",
"resource://gre/modules/SocialService.jsm");
let Social = {
lastEventReceived: 0,
provider: null,
init: function Social_init(callback) {
if (this.provider) {
@ -38,6 +39,25 @@ let Social = {
return this.provider && this.provider.enabled && this.provider.port;
},
set enabled(val) {
SocialService.enabled = val;
},
get enabled() {
return SocialService.enabled;
},
get active() {
return Services.prefs.getBoolPref("social.active");
},
set active(val) {
Services.prefs.setBoolPref("social.active", !!val);
this.enabled = !!val;
},
toggle: function Social_toggle() {
this.enabled = !this.enabled;
},
toggleSidebar: function SocialSidebar_toggle() {
let prefValue = Services.prefs.getBoolPref("social.sidebar.open");
Services.prefs.setBoolPref("social.sidebar.open", !prefValue);

Просмотреть файл

@ -228,8 +228,8 @@ let AlarmService = {
if (this._currentAlarm) {
debug("Fire system intent: " + JSON.stringify(this._currentAlarm));
if (this._currentAlarm.manifestURL)
messenger.sendMessage("alarm", this._currentAlarm, this._currentAlarm.manifestURL);
let manifestURI = Services.io.newURI(this._currentAlarm.manifestURL, null, null);
messenger.sendMessage("alarm", this._currentAlarm, manifestURI);
this._currentAlarm = null;
}
@ -244,8 +244,8 @@ let AlarmService = {
// fire system intent for it instead of setting it
if (nextAlarmTime <= nowTime) {
debug("Fire system intent: " + JSON.stringify(nextAlarm));
if (nextAlarm.manifestURL)
messenger.sendMessage("alarm", nextAlarm, nextAlarm.manifestURL);
let manifestURI = Services.io.newURI(nextAlarm.manifestURL, null, null);
messenger.sendMessage("alarm", nextAlarm, manifestURI);
} else {
this._currentAlarm = nextAlarm;
break;

Просмотреть файл

@ -45,6 +45,11 @@ AlarmsManager.prototype = {
add: function add(aDate, aRespectTimezone, aData) {
debug("add()");
if (!this._manifestURL) {
debug("Cannot add alarms for non-installed apps.");
throw Components.results.NS_ERROR_FAILURE;
}
let isIgnoreTimezone = true;
switch (aRespectTimezone) {
case "honorTimezone":
@ -150,8 +155,7 @@ AlarmsManager.prototype = {
// Get the manifest URL if this is an installed app
this._manifestURL = null;
let utils = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
let utils = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
let app = utils.getApp();
if (app)
this._manifestURL = app.manifestURL;

Просмотреть файл

@ -60,6 +60,7 @@ let RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = false;
let RILQUIRKS_V5_LEGACY = true;
let RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL = false;
let RILQUIRKS_MODEM_DEFAULTS_TO_EMERGENCY_MODE = false;
let RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS = false;
/**
* This object contains helpers buffering incoming data & deconstructing it
@ -727,6 +728,10 @@ let RIL = {
case "Qualcomm RIL 1.0":
let product_model = libcutils.property_get("ro.product.model");
if (DEBUG) debug("Detected product model " + product_model);
if (product_model == "otoro1") {
if (DEBUG) debug("Enabling RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS.");
RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS = true;
}
if (DEBUG) {
debug("Detected Qualcomm RIL 1.0, " +
"disabling RILQUIRKS_V5_LEGACY and " +
@ -2825,6 +2830,12 @@ RIL[REQUEST_GET_SIM_STATUS] = function REQUEST_GET_SIM_STATUS(length, options) {
pin1: Buf.readUint32(),
pin2: Buf.readUint32()
});
if (RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS) {
Buf.readUint32();
Buf.readUint32();
Buf.readUint32();
Buf.readUint32();
}
}
if (DEBUG) debug("iccStatus: " + JSON.stringify(iccStatus));

Просмотреть файл

@ -7,7 +7,9 @@
#include "nsEditor.h"
#include "IMETextTxn.h"
#include "nsGkAtoms.h"
#include "nsISelection.h"
#include "mozilla/Selection.h"
using namespace mozilla;
PlaceholderTxn::PlaceholderTxn() : EditAggregateTxn(),
mAbsorb(true),
@ -42,7 +44,9 @@ NS_INTERFACE_MAP_END_INHERITING(EditAggregateTxn)
NS_IMPL_ADDREF_INHERITED(PlaceholderTxn, EditAggregateTxn)
NS_IMPL_RELEASE_INHERITED(PlaceholderTxn, EditAggregateTxn)
NS_IMETHODIMP PlaceholderTxn::Init(nsIAtom *aName, nsSelectionState *aSelState, nsIEditor *aEditor)
NS_IMETHODIMP
PlaceholderTxn::Init(nsIAtom* aName, nsSelectionState* aSelState,
nsEditor* aEditor)
{
NS_ENSURE_TRUE(aEditor && aSelState, NS_ERROR_NULL_POINTER);
@ -256,10 +260,9 @@ NS_IMETHODIMP PlaceholderTxn::Commit()
NS_IMETHODIMP PlaceholderTxn::RememberEndingSelection()
{
nsCOMPtr<nsISelection> selection;
nsresult res = mEditor->GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = mEditor->GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
return mEndSel.SaveSelection(selection);
mEndSel.SaveSelection(selection);
return NS_OK;
}

Просмотреть файл

@ -44,7 +44,8 @@ public:
// ------------ nsIAbsorbingTransaction -----------------------
NS_IMETHOD Init(nsIAtom *aName, nsSelectionState *aSelState, nsIEditor *aEditor);
NS_IMETHOD Init(nsIAtom* aName, nsSelectionState* aSelState,
nsEditor* aEditor);
NS_IMETHOD GetTxnName(nsIAtom **aName);
@ -72,7 +73,7 @@ protected:
// selection properly.
nsAutoPtr<nsSelectionState> mStartSel; // use a pointer because this is constructed before we exist
nsSelectionState mEndSel;
nsIEditor* mEditor; /** the editor for this transaction */
nsEditor* mEditor; /** the editor for this transaction */
};

Просмотреть файл

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html contenteditable="true">
<head>
<script>
function boom()
{
document.execCommand("inserthtml", false, "b");
var myrange = document.createRange();
myrange.selectNodeContents(document.getElementsByTagName("img")[0]);
window.getSelection().addRange(myrange);
document.execCommand("strikethrough", false, null);
}
</script>
</head>
<body onload="boom();"><img></body>
</html>

Просмотреть файл

@ -17,3 +17,4 @@ load 766845.xhtml
load 768765.html
needs-focus load 771749.html
load 772282.html
load 776323.html

Просмотреть файл

@ -904,9 +904,8 @@ nsEditor::BeginPlaceHolderTransaction(nsIAtom *aName)
BeginUpdateViewBatch();
mPlaceHolderTxn = nsnull;
mPlaceHolderName = aName;
nsCOMPtr<nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(res)) {
nsRefPtr<Selection> selection = GetSelection();
if (selection) {
mSelState = new nsSelectionState();
mSelState->SaveSelection(selection);
}
@ -1979,7 +1978,7 @@ nsEditor::ArePreservingSelection()
}
void
nsEditor::PreserveSelectionAcrossActions(nsISelection *aSel)
nsEditor::PreserveSelectionAcrossActions(Selection* aSel)
{
mSavedSel.SaveSelection(aSel);
mRangeUpdater.RegisterSelectionState(mSavedSel);

Просмотреть файл

@ -425,7 +425,7 @@ public:
/** routines for managing the preservation of selection across
* various editor actions */
bool ArePreservingSelection();
void PreserveSelectionAcrossActions(nsISelection *aSel);
void PreserveSelectionAcrossActions(mozilla::Selection* aSel);
nsresult RestorePreservedSelection(nsISelection *aSel);
void StopPreservingSelection();

Просмотреть файл

@ -3,7 +3,7 @@
* 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/. */
#include "mozilla/Selection.h"
#include "nsCOMArray.h"
#include "nsComponentManagerUtils.h"
#include "nsEditorUtils.h"
@ -18,24 +18,23 @@
#include "nsIDocument.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsINode.h"
#include "nsISelection.h"
#include "nsISimpleEnumerator.h"
class nsIDOMRange;
class nsISupports;
using namespace mozilla;
/******************************************************************************
* nsAutoSelectionReset
*****************************************************************************/
nsAutoSelectionReset::nsAutoSelectionReset(nsISelection *aSel, nsEditor *aEd) :
mSel(nsnull)
,mEd(nsnull)
nsAutoSelectionReset::nsAutoSelectionReset(Selection* aSel, nsEditor* aEd)
: mSel(nsnull), mEd(nsnull)
{
if (!aSel || !aEd) return; // not much we can do, bail.
if (aEd->ArePreservingSelection()) return; // we already have initted mSavedSel, so this must be nested call.
mSel = do_QueryInterface(aSel);
mSel = aSel;
mEd = aEd;
if (mSel)
{

Просмотреть файл

@ -57,12 +57,12 @@ class NS_STACK_CLASS nsAutoSelectionReset
{
private:
/** ref-counted reference to the selection that we are supposed to restore */
nsCOMPtr<nsISelection> mSel;
nsRefPtr<mozilla::Selection> mSel;
nsEditor *mEd; // non-owning ref to nsEditor
public:
/** constructor responsible for remembering all state needed to restore aSel */
nsAutoSelectionReset(nsISelection *aSel, nsEditor *aEd);
nsAutoSelectionReset(mozilla::Selection* aSel, nsEditor* aEd);
/** destructor restores mSel to its former state */
~nsAutoSelectionReset();

Просмотреть файл

@ -32,7 +32,8 @@ public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IABSORBINGTRANSACTION_IID)
NS_IMETHOD Init(nsIAtom *aName, nsSelectionState *aSelState, nsIEditor *aEditor)=0;
NS_IMETHOD Init(nsIAtom* aName, nsSelectionState* aSelState,
nsEditor* aEditor) = 0;
NS_IMETHOD EndPlaceHolderBatch()=0;

Просмотреть файл

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/Selection.h" // for Selection
#include "nsAString.h" // for nsAString_internal::Length
#include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc
#include "nsCycleCollectionParticipant.h"
@ -19,6 +20,7 @@
#include "nsRange.h" // for nsRange
#include "nsSelectionState.h"
using namespace mozilla;
/***************************************************************************
* class for recording selection info. stores selection as collection of
@ -47,43 +49,30 @@ nsSelectionState::DoTraverse(nsCycleCollectionTraversalCallback &cb)
}
}
nsresult
nsSelectionState::SaveSelection(nsISelection *aSel)
void
nsSelectionState::SaveSelection(Selection* aSel)
{
NS_ENSURE_TRUE(aSel, NS_ERROR_NULL_POINTER);
PRInt32 i,rangeCount, arrayCount = mArray.Length();
aSel->GetRangeCount(&rangeCount);
MOZ_ASSERT(aSel);
PRInt32 arrayCount = mArray.Length();
PRInt32 rangeCount = aSel->GetRangeCount();
// if we need more items in the array, new them
if (arrayCount<rangeCount)
{
PRInt32 count = rangeCount-arrayCount;
for (i=0; i<count; i++)
{
if (arrayCount < rangeCount) {
for (PRInt32 i = arrayCount; i < rangeCount; i++) {
mArray.AppendElement();
mArray[i] = new nsRangeStore();
}
}
// else if we have too many, delete them
else if (arrayCount>rangeCount)
{
for (i = arrayCount-1; i >= rangeCount; i--)
{
} else if (arrayCount > rangeCount) {
// else if we have too many, delete them
for (PRInt32 i = arrayCount - 1; i >= rangeCount; i--) {
mArray.RemoveElementAt(i);
}
}
// now store the selection ranges
nsresult res = NS_OK;
for (i=0; i<rangeCount; i++)
{
nsCOMPtr<nsIDOMRange> range;
res = aSel->GetRangeAt(i, getter_AddRefs(range));
mArray[i]->StoreRange(range);
for (PRInt32 i = 0; i < rangeCount; i++) {
mArray[i]->StoreRange(aSel->GetRangeAt(i));
}
return res;
}
nsresult

Просмотреть файл

@ -18,6 +18,9 @@ class nsIDOMCharacterData;
class nsIDOMRange;
class nsISelection;
class nsRange;
namespace mozilla {
class Selection;
}
/***************************************************************************
* class for recording selection info. stores selection as collection of
@ -52,7 +55,7 @@ class nsSelectionState
void DoTraverse(nsCycleCollectionTraversalCallback &cb);
void DoUnlink() { MakeEmpty(); }
nsresult SaveSelection(nsISelection *aSel);
void SaveSelection(mozilla::Selection *aSel);
nsresult RestoreSelection(nsISelection *aSel);
bool IsCollapsed();
bool IsEqual(nsSelectionState *aSelState);

Просмотреть файл

@ -2869,7 +2869,7 @@ nsHTMLEditRules::DidDeleteSelection(nsISelection *aSelection,
}
nsresult
nsHTMLEditRules::WillMakeList(nsISelection* aSelection,
nsHTMLEditRules::WillMakeList(Selection* aSelection,
const nsAString* aListType,
bool aEntireList,
const nsAString* aBulletType,
@ -3159,7 +3159,7 @@ nsHTMLEditRules::WillMakeList(nsISelection* aSelection,
nsresult
nsHTMLEditRules::WillRemoveList(nsISelection *aSelection,
nsHTMLEditRules::WillRemoveList(Selection* aSelection,
bool aOrdered,
bool *aCancel,
bool *aHandled)
@ -3226,7 +3226,7 @@ nsHTMLEditRules::WillRemoveList(nsISelection *aSelection,
nsresult
nsHTMLEditRules::WillMakeDefListItem(nsISelection *aSelection,
nsHTMLEditRules::WillMakeDefListItem(Selection* aSelection,
const nsAString *aItemType,
bool aEntireList,
bool *aCancel,
@ -3238,7 +3238,7 @@ nsHTMLEditRules::WillMakeDefListItem(nsISelection *aSelection,
}
nsresult
nsHTMLEditRules::WillMakeBasicBlock(nsISelection *aSelection,
nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection,
const nsAString *aBlockType,
bool *aCancel,
bool *aHandled)
@ -3395,7 +3395,8 @@ nsHTMLEditRules::DidMakeBasicBlock(nsISelection *aSelection,
}
nsresult
nsHTMLEditRules::WillIndent(nsISelection *aSelection, bool *aCancel, bool * aHandled)
nsHTMLEditRules::WillIndent(Selection* aSelection,
bool* aCancel, bool* aHandled)
{
nsresult res;
if (mHTMLEditor->IsCSSEnabled()) {
@ -3408,7 +3409,8 @@ nsHTMLEditRules::WillIndent(nsISelection *aSelection, bool *aCancel, bool * aHan
}
nsresult
nsHTMLEditRules::WillCSSIndent(nsISelection *aSelection, bool *aCancel, bool * aHandled)
nsHTMLEditRules::WillCSSIndent(Selection* aSelection,
bool* aCancel, bool* aHandled)
{
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
@ -3614,7 +3616,8 @@ nsHTMLEditRules::WillCSSIndent(nsISelection *aSelection, bool *aCancel, bool * a
}
nsresult
nsHTMLEditRules::WillHTMLIndent(nsISelection *aSelection, bool *aCancel, bool * aHandled)
nsHTMLEditRules::WillHTMLIndent(Selection* aSelection,
bool* aCancel, bool* aHandled)
{
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
nsresult res = WillInsert(aSelection, aCancel);
@ -3842,7 +3845,8 @@ nsHTMLEditRules::WillHTMLIndent(nsISelection *aSelection, bool *aCancel, bool *
nsresult
nsHTMLEditRules::WillOutdent(nsISelection *aSelection, bool *aCancel, bool *aHandled)
nsHTMLEditRules::WillOutdent(Selection* aSelection,
bool* aCancel, bool* aHandled)
{
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
// initialize out param
@ -4412,7 +4416,7 @@ nsHTMLEditRules::IsEmptyBlock(nsIDOMNode *aNode,
nsresult
nsHTMLEditRules::WillAlign(nsISelection *aSelection,
nsHTMLEditRules::WillAlign(Selection* aSelection,
const nsAString *alignType,
bool *aCancel,
bool *aHandled)
@ -8570,7 +8574,8 @@ nsHTMLEditRules::RelativeChangeIndentationOfElementNode(nsIDOMNode *aNode, PRInt
//
nsresult
nsHTMLEditRules::WillAbsolutePosition(nsISelection *aSelection, bool *aCancel, bool * aHandled)
nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection,
bool* aCancel, bool* aHandled)
{
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
nsresult res = WillInsert(aSelection, aCancel);
@ -8786,8 +8791,8 @@ nsHTMLEditRules::DidAbsolutePosition()
}
nsresult
nsHTMLEditRules::WillRemoveAbsolutePosition(nsISelection *aSelection, bool *aCancel, bool * aHandled)
{
nsHTMLEditRules::WillRemoveAbsolutePosition(Selection* aSelection,
bool* aCancel, bool* aHandled) {
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
nsresult res = WillInsert(aSelection, aCancel);
NS_ENSURE_SUCCESS(res, res);
@ -8808,7 +8813,7 @@ nsHTMLEditRules::WillRemoveAbsolutePosition(nsISelection *aSelection, bool *aCan
}
nsresult
nsHTMLEditRules::WillRelativeChangeZIndex(nsISelection *aSelection,
nsHTMLEditRules::WillRelativeChangeZIndex(Selection* aSelection,
PRInt32 aChange,
bool *aCancel,
bool * aHandled)

Просмотреть файл

@ -156,18 +156,38 @@ protected:
nsresult MoveNodeSmart(nsIDOMNode *aSource, nsIDOMNode *aDest, PRInt32 *aOffset);
nsresult MoveContents(nsIDOMNode *aSource, nsIDOMNode *aDest, PRInt32 *aOffset);
nsresult DeleteNonTableElements(nsINode* aNode);
nsresult WillMakeList(nsISelection *aSelection, const nsAString *aListType, bool aEntireList, const nsAString *aBulletType, bool *aCancel, bool *aHandled, const nsAString *aItemType=nsnull);
nsresult WillRemoveList(nsISelection *aSelection, bool aOrderd, bool *aCancel, bool *aHandled);
nsresult WillIndent(nsISelection *aSelection, bool *aCancel, bool *aHandled);
nsresult WillCSSIndent(nsISelection *aSelection, bool *aCancel, bool *aHandled);
nsresult WillHTMLIndent(nsISelection *aSelection, bool *aCancel, bool *aHandled);
nsresult WillOutdent(nsISelection *aSelection, bool *aCancel, bool *aHandled);
nsresult WillAlign(nsISelection *aSelection, const nsAString *alignType, bool *aCancel, bool *aHandled);
nsresult WillAbsolutePosition(nsISelection *aSelection, bool *aCancel, bool * aHandled);
nsresult WillRemoveAbsolutePosition(nsISelection *aSelection, bool *aCancel, bool * aHandled);
nsresult WillRelativeChangeZIndex(nsISelection *aSelection, PRInt32 aChange, bool *aCancel, bool * aHandled);
nsresult WillMakeDefListItem(nsISelection *aSelection, const nsAString *aBlockType, bool aEntireList, bool *aCancel, bool *aHandled);
nsresult WillMakeBasicBlock(nsISelection *aSelection, const nsAString *aBlockType, bool *aCancel, bool *aHandled);
nsresult WillMakeList(mozilla::Selection* aSelection,
const nsAString* aListType,
bool aEntireList,
const nsAString* aBulletType,
bool* aCancel, bool* aHandled,
const nsAString* aItemType = nsnull);
nsresult WillRemoveList(mozilla::Selection* aSelection,
bool aOrdered, bool* aCancel, bool* aHandled);
nsresult WillIndent(mozilla::Selection* aSelection,
bool* aCancel, bool* aHandled);
nsresult WillCSSIndent(mozilla::Selection* aSelection,
bool* aCancel, bool* aHandled);
nsresult WillHTMLIndent(mozilla::Selection* aSelection,
bool* aCancel, bool* aHandled);
nsresult WillOutdent(mozilla::Selection* aSelection,
bool* aCancel, bool* aHandled);
nsresult WillAlign(mozilla::Selection* aSelection,
const nsAString* alignType,
bool* aCancel, bool* aHandled);
nsresult WillAbsolutePosition(mozilla::Selection* aSelection,
bool* aCancel, bool* aHandled);
nsresult WillRemoveAbsolutePosition(mozilla::Selection* aSelection,
bool* aCancel, bool* aHandled);
nsresult WillRelativeChangeZIndex(mozilla::Selection* aSelection,
PRInt32 aChange,
bool* aCancel, bool* aHandled);
nsresult WillMakeDefListItem(mozilla::Selection* aSelection,
const nsAString* aBlockType, bool aEntireList,
bool* aCancel, bool* aHandled);
nsresult WillMakeBasicBlock(mozilla::Selection* aSelection,
const nsAString* aBlockType,
bool* aCancel, bool* aHandled);
nsresult DidMakeBasicBlock(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
nsresult DidAbsolutePosition();
nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType);

Просмотреть файл

@ -3379,15 +3379,13 @@ SetSelectionAroundHeadChildren(nsISelection* aSelection,
NS_IMETHODIMP
nsHTMLEditor::GetHeadContentsAsHTML(nsAString& aOutputString)
{
nsCOMPtr<nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
// Save current selection
nsAutoSelectionReset selectionResetter(selection, this);
res = SetSelectionAroundHeadChildren(selection, mDocWeak);
nsresult res = SetSelectionAroundHeadChildren(selection, mDocWeak);
NS_ENSURE_SUCCESS(res, res);
res = OutputToString(NS_LITERAL_STRING("text/html"),

Просмотреть файл

@ -1535,11 +1535,8 @@ nsHTMLEditor::RelativeFontChange( PRInt32 aSizeChange)
ForceCompositionEnd();
// Get the selection
nsCOMPtr<nsISelection>selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
// Is the selection collapsed?
// if it's collapsed set typing state
if (selection->Collapsed()) {
@ -1554,7 +1551,7 @@ nsHTMLEditor::RelativeFontChange( PRInt32 aSizeChange)
NS_ENSURE_TRUE(selectedNode, NS_OK);
if (IsTextNode(selectedNode)) {
nsCOMPtr<nsIDOMNode> parent;
res = selectedNode->GetParentNode(getter_AddRefs(parent));
nsresult res = selectedNode->GetParentNode(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(res, res);
selectedNode = parent;
}
@ -1575,7 +1572,7 @@ nsHTMLEditor::RelativeFontChange( PRInt32 aSizeChange)
// get selection range enumerator
nsCOMPtr<nsIEnumerator> enumerator;
res = selPriv->GetEnumerator(getter_AddRefs(enumerator));
nsresult res = selection->GetEnumerator(getter_AddRefs(enumerator));
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);

Просмотреть файл

@ -6,6 +6,7 @@
#include <stdio.h>
#include "mozilla/Assertions.h"
#include "mozilla/Selection.h"
#include "mozilla/dom/Element.h"
#include "nsAString.h"
#include "nsAlgorithm.h"
@ -28,8 +29,6 @@
#include "nsIHTMLEditor.h"
#include "nsINode.h"
#include "nsIPresShell.h"
#include "nsISelection.h"
#include "nsISelectionPrivate.h" // For nsISelectionPrivate::TABLESELECTION_ defines
#include "nsISupportsUtils.h"
#include "nsITableCellLayout.h" // For efficient access to table cell
#include "nsITableEditor.h"
@ -1953,9 +1952,7 @@ nsHTMLEditor::SwitchTableCellHeaderType(nsIDOMElement *aSourceCell, nsIDOMElemen
// Save current selection to restore when done
// This is needed so ReplaceContainer can monitor selection
// when replacing nodes
nsCOMPtr<nsISelection>selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
nsAutoSelectionReset selectionResetter(selection, this);
@ -1965,7 +1962,8 @@ nsHTMLEditor::SwitchTableCellHeaderType(nsIDOMElement *aSourceCell, nsIDOMElemen
// This creates new node, moves children, copies attributes (true)
// and manages the selection!
res = ReplaceContainer(aSourceCell, address_of(newNode), newCellType, nsnull, nsnull, true);
nsresult res = ReplaceContainer(aSourceCell, address_of(newNode),
newCellType, nsnull, nsnull, true);
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(newNode, NS_ERROR_FAILURE);
@ -2491,13 +2489,12 @@ nsHTMLEditor::FixBadColSpan(nsIDOMElement *aTable, PRInt32 aColIndex, PRInt32& a
NS_IMETHODIMP
nsHTMLEditor::NormalizeTable(nsIDOMElement *aTable)
{
nsCOMPtr<nsISelection>selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMElement> table;
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aTable, getter_AddRefs(table));
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"),
aTable, getter_AddRefs(table));
NS_ENSURE_SUCCESS(res, res);
// Don't fail if we didn't find a table
NS_ENSURE_TRUE(table, NS_OK);

Просмотреть файл

@ -3641,6 +3641,29 @@ gfxFontGroup::InitScriptRun(gfxContext *aContext,
}
}
already_AddRefed<gfxFont>
gfxFontGroup::TryOtherFamilyMembers(gfxFont* aFont, PRUint32 aCh)
{
gfxFontFamily *family = aFont->GetFontEntry()->Family();
if (family && !aFont->GetFontEntry()->mIsProxy &&
family->TestCharacterMap(aCh)) {
// Note that we don't need the actual runScript in matchData for
// gfxFontFamily::SearchAllFontsForChar, it's only used for the
// system-fallback case. So we can just set it to 0 here.
GlobalFontMatch matchData(aCh, 0, &mStyle);
family->SearchAllFontsForChar(&matchData);
gfxFontEntry *fe = matchData.mBestMatch;
if (fe) {
bool needsBold = aFont->GetStyle()->weight >= 600 && !fe->IsBold();
nsRefPtr<gfxFont> font = fe->FindOrMakeFont(&mStyle, needsBold);
if (font) {
return font.forget();
}
}
}
return nsnull;
}
already_AddRefed<gfxFont>
gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
PRInt32 aRunScript, gfxFont *aPrevMatchedFont,
@ -3660,6 +3683,13 @@ gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
firstFont->AddRef();
return firstFont;
}
// It's possible that another font in the family (e.g. regular face,
// where the requested style was italic) will support the character
nsRefPtr<gfxFont> font = TryOtherFamilyMembers(firstFont, aCh);
if (font) {
*aMatchType = gfxTextRange::kFontGroup;
return font.forget();
}
// we don't need to check the first font again below
++nextIndex;
}
@ -3705,22 +3735,10 @@ gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
return font.forget();
}
// check other faces of the family
gfxFontFamily *family = font->GetFontEntry()->Family();
if (family && !font->GetFontEntry()->mIsProxy &&
family->TestCharacterMap(aCh))
{
GlobalFontMatch matchData(aCh, aRunScript, &mStyle);
family->SearchAllFontsForChar(&matchData);
gfxFontEntry *fe = matchData.mBestMatch;
if (fe) {
bool needsBold =
font->GetStyle()->weight >= 600 && !fe->IsBold();
font = fe->FindOrMakeFont(font->GetStyle(), needsBold);
if (font) {
return font.forget();
}
}
font = TryOtherFamilyMembers(font, aCh);
if (font) {
*aMatchType = gfxTextRange::kFontGroup;
return font.forget();
}
}

Просмотреть файл

@ -3181,6 +3181,12 @@ protected:
FontCreationCallback fc,
void *closure);
// Helper for font-matching:
// see if aCh is supported in any of the other faces from aFont's family;
// if so return the best style match, else return null.
already_AddRefed<gfxFont> TryOtherFamilyMembers(gfxFont* aFont,
PRUint32 aCh);
static bool FontResolverProc(const nsAString& aName, void *aClosure);
static bool FindPlatformFont(const nsAString& aName,

Просмотреть файл

@ -85,6 +85,86 @@ GetBuildConfiguration(JSContext *cx, unsigned argc, jsval *vp)
if (!JS_SetProperty(cx, info, "has-gczeal", &value))
return false;
#ifdef JS_MORE_DETERMINISTIC
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "more-deterministic", &value))
return false;
#ifdef MOZ_PROFILING
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "profiling", &value))
return false;
#ifdef INCLUDE_MOZILLA_DTRACE
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "dtrace", &value))
return false;
#ifdef MOZ_TRACE_JSCALLS
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "trace-jscalls-api", &value))
return false;
#ifdef JSGC_INCREMENTAL
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "incremental-gc", &value))
return false;
#ifdef JSGC_GENERATIONAL
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "generational-gc", &value))
return false;
#ifdef MOZ_VALGRIND
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "valgrind", &value))
return false;
#ifdef JS_OOM_DO_BACKTRACES
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "oom-backtraces", &value))
return false;
#ifdef JS_METHODJIT
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "methodjit", &value))
return false;
#ifdef JS_HAS_XML_SUPPORT
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "e4x", &value))
return false;
*vp = ObjectValue(*info);
return true;
}

Просмотреть файл

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<style id="s"></style>
<script>
function boom() { document.getElementById("s").textContent = "div { opacity: 0.5; }"; }
</script>
</head>
<body onload="document.documentElement.offsetHeight; boom();">
<div><div>X</div></div>
</body>
</html>

Просмотреть файл

@ -358,3 +358,4 @@ asserts-if(winWidget,0-2) load 736924-1.html # bug 738803
load 749816-1.html
load 763223-1.html
test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) load 763702.xhtml
load 770381-1.html

Просмотреть файл

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Bug 769475 - test for italicized Arabic script in Arial</title>
<style type="text/css">
body {
font-family: arial, serif;
font-size: 36px;
line-height: 72px;
}
span {
color: white;
}
</style>
</head>
<body lang="ar">
<!-- the white span should have the same width whether it's italicized or not,
-- as Arial does not have Arabic characters in the italic face but we should
-- apply synthetic italic to the regular face, NOT fall back to a different
-- family from prefs.
-->
<div>العربي <span>العربي</span> العربي</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Bug 769475 - test for italicized Arabic script in Arial</title>
<style type="text/css">
body {
font-family: arial, serif;
font-size: 36px;
line-height: 72px;
}
span {
font-style: italic;
color: white;
}
</style>
</head>
<body lang="ar">
<!-- the white span should have the same width whether it's italicized or not,
-- as Arial does not have Arabic characters in the italic face but we should
-- apply synthetic italic to the regular face, NOT fall back to a different
-- family from prefs.
-->
<div>العربي <span>العربي</span> العربي</div>
</body>
</html>

Просмотреть файл

@ -81,3 +81,7 @@ HTTP(..) == font-stretch-1.html font-stretch-1-ref.html
random-if(!(cocoaWidget||/^Windows\x20NT\x206\.1/.test(http.oscpu))) skip-if(gtk2Widget) != bold-system-fallback-1.html bold-system-fallback-1-notref.html
# test 2 uses Chess symbols; expected to pass on Android
random-if(!Android) skip-if(gtk2Widget) != bold-system-fallback-2.html bold-system-fallback-2-notref.html
# Bug 769475 - applying 'italic' to Arabic text in Arial should NOT change family or metrics.
# Expected to pass on MacOSX and Windows; other platforms unknown, depending on font availability.
random-if(!(cocoaWidget||winWidget)) == arial-arabic.html arial-arabic-ref.html

Просмотреть файл

@ -129,8 +129,7 @@ nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement,
}
}
nsPresContext *presCtx = aPresShell->GetPresContext();
MOZ_ASSERT(presCtx);
MOZ_ASSERT(aPresShell->GetPresContext());
}

Просмотреть файл

@ -33,7 +33,7 @@ function getFrameWorkerHandle(url, clientWindow, name) {
let existingWorker = workerCache[url];
if (!existingWorker) {
// setup the worker and add this connection to the pending queue
let worker = new FrameWorker(url, clientWindow, name);
let worker = new FrameWorker(url, name);
worker.pendingPorts.push(clientPort);
existingWorker = workerCache[url] = worker;
} else {
@ -253,11 +253,6 @@ function WorkerHandle(port, worker) {
this._worker = worker;
}
WorkerHandle.prototype = {
__exposedProps__: {
port: "r",
terminate: "r"
},
// XXX - workers have no .close() method, but *do* have a .terminate()
// method which we should implement. However, the worker spec doesn't define
// a callback to be made in the worker when this happens - it all just dies.
@ -329,7 +324,7 @@ function initClientMessageHandler(worker, workerWindow) {
* @param {nsiDOMWindow} clientWindow, optional
*/
function ClientPort(portid, clientWindow) {
this._clientWindow = clientWindow
this._clientWindow = clientWindow;
this._window = null;
// messages posted to the worker before the worker has loaded.
this._pendingMessagesOutgoing = [];
@ -338,17 +333,17 @@ function ClientPort(portid, clientWindow) {
ClientPort.prototype = {
__exposedProps__: {
'port': 'r',
'onmessage': 'rw',
'postMessage': 'r',
'close': 'r'
onmessage: "rw",
postMessage: "r",
close: "r",
toString: "r"
},
__proto__: AbstractPort.prototype,
_portType: "client",
_JSONParse: function fw_ClientPort_JSONParse(data) {
if (this._clientWindow) {
return this._clientWindow.JSON.parse(data);
return XPCNativeWrapper.unwrap(this._clientWindow).JSON.parse(data);
}
return JSON.parse(data);
},
@ -383,6 +378,7 @@ ClientPort.prototype = {
this.postMessage({topic: "social.port-closing"});
AbstractPort.prototype.close.call(this);
this._window = null;
this._clientWindow = null;
this._pendingMessagesOutgoing = null;
}
}

Просмотреть файл

@ -15,6 +15,7 @@ EXTRA_JS_MODULES = \
MessagePortWorker.js \
SocialService.jsm \
WorkerAPI.jsm \
MozSocialAPI.jsm \
$(NULL)
TEST_DIRS += \

Просмотреть файл

@ -29,17 +29,12 @@ AbstractPort.prototype = {
_JSONParse: function fw_AbstractPort_JSONParse(data) JSON.parse(data),
_postControlMessage: function fw_AbstractPort_postControlMessage(topic, data) {
let postData = {portTopic: topic,
portId: this._portid,
portFromType: this._portType,
data: data,
__exposedProps__: {
portTopic: 'r',
portId: 'r',
portFromType: 'r',
data: 'r'
}
};
let postData = {
portTopic: topic,
portId: this._portid,
portFromType: this._portType,
data: data
};
this._dopost(postData);
},
@ -52,14 +47,15 @@ AbstractPort.prototype = {
data = this._JSONParse(data);
if (!this._handler) {
this._pendingMessagesIncoming.push(data);
}
else {
} else {
try {
this._handler({data: data,
__exposedProps__: {data: 'r'}
});
}
catch (ex) {
this._handler({
data: data,
__exposedProps__: {
data: 'r'
}
});
} catch (ex) {
this._onerror(ex);
}
}
@ -71,6 +67,9 @@ AbstractPort.prototype = {
this._onmessage(this._pendingMessagesIncoming.shift());
}
},
get onmessage() {
return this._handler;
},
/**
* postMessage

Просмотреть файл

@ -0,0 +1,130 @@
/* 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 { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SocialService", "resource://gre/modules/SocialService.jsm");
const EXPORTED_SYMBOLS = ["MozSocialAPI"];
var MozSocialAPI = {
_enabled: false,
set enabled(val) {
let enable = !!val;
if (enable == this._enabled) {
return;
}
this._enabled = enable;
if (enable) {
Services.obs.addObserver(injectController, "document-element-inserted", false);
} else {
Services.obs.removeObserver(injectController, "document-element-inserted", false);
}
}
};
// Called on document-element-inserted, checks that the API should be injected,
// and then calls attachToWindow as appropriate
function injectController(doc, topic, data) {
try {
let window = doc.defaultView;
if (!window)
return;
var containingBrowser = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell)
.chromeEventHandler;
// If the containing browser isn't one of the social browsers, nothing to
// do here.
// XXX this is app-specific, might want some mechanism for consumers to
// whitelist other IDs/windowtypes
if (!(containingBrowser.id == "social-sidebar-browser" ||
containingBrowser.id == "social-notification-browser")) {
return;
}
let origin = containingBrowser.getAttribute("origin");
if (!origin) {
return;
}
SocialService.getProvider(origin, function(provider) {
if (provider && provider.workerURL) {
attachToWindow(provider, window);
}
});
} catch(e) {
Cu.reportError("MozSocialAPI injectController: unable to attachToWindow for " + doc.location + ": " + e);
}
}
// Loads mozSocial support functions associated with provider into targetWindow
function attachToWindow(provider, targetWindow) {
let origin = provider.origin;
if (!provider.enabled) {
throw new Error("MozSocialAPI: cannot attach disabled provider " + origin);
}
let targetDocURI = targetWindow.document.documentURIObject;
if (provider.origin != targetDocURI.prePath) {
throw new Error("MozSocialAPI: cannot attach " + origin + " to " + targetDocURI.spec);
}
var port = provider._getWorkerPort(targetWindow);
let mozSocialObj = {
// Use a method for backwards compat with existing providers, but we
// should deprecate this in favor of a simple .port getter.
getWorker: function() {
return {
port: port,
__exposedProps__: {
port: "r"
}
};
},
hasBeenIdleFor: function () {
return false;
}
};
let contentObj = Cu.createObjectIn(targetWindow);
let propList = {};
for (let prop in mozSocialObj) {
propList[prop] = {
enumerable: true,
configurable: true,
writable: true,
value: mozSocialObj[prop]
};
}
Object.defineProperties(contentObj, propList);
Cu.makeObjectPropsNormal(contentObj);
targetWindow.navigator.wrappedJSObject.__defineGetter__("mozSocial", function() {
// We do this in a getter, so that we create these objects
// only on demand (this is a potential concern, since
// otherwise we might add one per iframe, and keep them
// alive for as long as the window is alive).
delete targetWindow.navigator.wrappedJSObject.mozSocial;
return targetWindow.navigator.wrappedJSObject.mozSocial = contentObj;
});
targetWindow.addEventListener("unload", function () {
// We want to close the port, but also want the target window to be
// able to use the port during an unload event they setup - so we
// set a timer which will fire after the unload events have all fired.
schedule(function () { port.close(); });
});
}
function schedule(callback) {
Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
}

Просмотреть файл

@ -8,6 +8,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/MozSocialAPI.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "getFrameWorkerHandle", "resource://gre/modules/FrameWorker.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "WorkerAPI", "resource://gre/modules/WorkerAPI.jsm");
@ -29,7 +30,7 @@ let SocialServiceInternal = {
XPCOMUtils.defineLazyGetter(SocialServiceInternal, "providers", function () {
// Initialize the service (add a pref observer)
function prefObserver(subject, topic, data) {
SocialService._setEnabled(Services.prefs.getBoolPref(data));
SocialService._setEnabled(Services.prefs.getBoolPref("social.enabled"));
}
Services.prefs.addObserver("social.enabled", prefObserver, false);
Services.obs.addObserver(function xpcomShutdown() {
@ -37,6 +38,9 @@ XPCOMUtils.defineLazyGetter(SocialServiceInternal, "providers", function () {
Services.prefs.removeObserver("social.enabled", prefObserver);
}, "xpcom-shutdown", false);
// Initialize the MozSocialAPI
MozSocialAPI.enabled = SocialServiceInternal.enabled;
// Now retrieve the providers
let providers = {};
let MANIFEST_PREFS = Services.prefs.getBranch("social.manifest.");
@ -77,6 +81,7 @@ const SocialService = {
_setEnabled: function _setEnabled(enable) {
SocialServiceInternal.providerArray.forEach(function (p) p.enabled = enable);
SocialServiceInternal.enabled = enable;
MozSocialAPI.enabled = enable;
Services.obs.notifyObservers(null, "social:pref-changed", enable ? "enabled" : "disabled");
},

Просмотреть файл

@ -32,7 +32,7 @@ let tests = {
ok(port, "should be able to get a port from the provider");
port.onmessage = function onMessage(event) {
let {topic, data} = event.data;
let topic = event.data.topic;
if (topic == "test-initialization-complete") {
is(provider.workerAPI.initialized, true, "workerAPI is now initialized");
next();