--- a/browser/themes/winstripe/browser/browser-aero.css
+++ b/browser/themes/winstripe/browser/browser-aero.css
@@ -136,20 +136,20 @@
#nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child:not(:-moz-lwtheme) {
background-color: transparent !important;
color: black;
text-shadow: 0 0 .5em white, 0 0 .5em white, 0 1px 0 rgba(255,255,255,.4);
border-left-style: none !important;
border-right-style: none !important;
}
- #toolbar-menubar :-moz-any(@primaryToolbarButtons@):not(#alltabs-button):not(#tabview-button):not(#new-tab-button) > .toolbarbutton-icon:not(:-moz-lwtheme),
- #TabsToolbar[tabsontop=true] :-moz-any(@primaryToolbarButtons@):not(#alltabs-button):not(#tabview-button):not(#new-tab-button) > .toolbarbutton-icon:not(:-moz-lwtheme),
- #navigator-toolbox[tabsontop=false] > #nav-bar :-moz-any(@primaryToolbarButtons@):not(#alltabs-button):not(#tabview-button):not(#new-tab-button) > .toolbarbutton-icon:not(:-moz-lwtheme),
- #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child :-moz-any(@primaryToolbarButtons@):not(#alltabs-button):not(#tabview-button):not(#new-tab-button) > .toolbarbutton-icon:not(:-moz-lwtheme) {
+ #toolbar-menubar :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
+ #TabsToolbar[tabsontop=true] :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
+ #navigator-toolbox[tabsontop=false] > #nav-bar :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
+ #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme) {
list-style-image: url("chrome://browser/skin/Toolbar-inverted.png");
}
/* Vertical toolbar border */
#main-window[sizemode=normal] #navigator-toolbox::after,
#main-window[sizemode=normal] #navigator-toolbox[tabsontop=true] > toolbar:not(#toolbar-menubar):not(#TabsToolbar),
#main-window[sizemode=normal] #navigator-toolbox[tabsontop=false] > toolbar:not(#toolbar-menubar):not(#nav-bar) {
border-left: 1px solid @toolbarShadowColor@;
--- a/mobile/chrome/content/content.js
+++ b/mobile/chrome/content/content.js
@@ -1346,18 +1346,18 @@ var SelectionHandler = {
let json = aMessage.json;
switch (aMessage.name) {
case "Browser:SelectionStart": {
// Clear out the text cache
this.selectedText = "";
// if this is an iframe, dig down to find the document that was clicked
- let x = json.x;
- let y = json.y;
+ let x = json.x - scrollOffset.x;
+ let y = json.y - scrollOffset.y;
let offset = scrollOffset;
let elem = utils.elementFromPoint(x, y, true, false);
while (elem && (elem instanceof HTMLIFrameElement || elem instanceof HTMLFrameElement)) {
// adjust client coordinates' origin to be top left of iframe viewport
let rect = elem.getBoundingClientRect();
scrollOffset = ContentScroll.getScrollOffset(elem.ownerDocument.defaultView);
offset.x += rect.left;
x -= rect.left;
@@ -1374,18 +1374,18 @@ var SelectionHandler = {
let currentDocShell = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell);
// Remove any previous selected or created ranges. Tapping anywhere on a
// page will create an empty range.
let selection = contentWindow.getSelection();
selection.removeAllRanges();
// Position the caret using a fake mouse click
- utils.sendMouseEventToWindow("mousedown", x - scrollOffset.x, y - scrollOffset.y, 0, 1, 0, true);
- utils.sendMouseEventToWindow("mouseup", x - scrollOffset.x, y - scrollOffset.y, 0, 1, 0, true);
+ utils.sendMouseEventToWindow("mousedown", x, y, 0, 1, 0, true);
+ utils.sendMouseEventToWindow("mouseup", x, y, 0, 1, 0, true);
// Select the word nearest the caret
try {
let selcon = currentDocShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay).QueryInterface(Ci.nsISelectionController);
selcon.wordMove(false, false);
selcon.wordMove(true, true);
} catch(e) {
// If we couldn't select the word at the given point, bail
@@ -1418,17 +1418,17 @@ var SelectionHandler = {
case "Browser:SelectionEnd": {
let tap = { x: json.x - this.cache.offset.x, y: json.y - this.cache.offset.y };
pointInSelection = (tap.x > this.cache.rect.left && tap.x < this.cache.rect.right) && (tap.y > this.cache.rect.top && tap.y < this.cache.rect.bottom);
try {
// The selection might already be gone
if (this.contentWindow)
- this.contentWindow.getSelection().collapseToStart();
+ this.contentWindow.getSelection().removeAllRanges();
this.contentWindow = null;
} catch(e) {}
if (pointInSelection && this.selectedText.length) {
let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
clipboard.copyString(this.selectedText);
sendAsyncMessage("Browser:SelectionCopied", { succeeded: true });
} else {
@@ -1445,29 +1445,34 @@ var SelectionHandler = {
let elemUnder = elementFromPoint(json.x - scrollOffset.x, json.y - scrollOffset.y);
if (elemUnder && elemUnder instanceof Ci.nsIDOMHTMLInputElement || elemUnder instanceof Ci.nsIDOMHTMLTextAreaElement)
return;
// Limit the selection to the initial content window (don't leave or enter iframes)
if (elemUnder && elemUnder.ownerDocument.defaultView != this.contentWindow)
return;
+ // Use fake mouse events to update the selection
if (json.type == "end") {
- this.cache.end.x = json.x - scrollOffset.x;
- this.cache.end.y = json.y - scrollOffset.y;
- utils.sendMouseEventToWindow("mousedown", this.cache.end.x, this.cache.end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
- utils.sendMouseEventToWindow("mouseup", this.cache.end.x, this.cache.end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
+ // Keep the cache in "client" coordinates, but translate for the mouse event
+ this.cache.end = { x: json.x, y: json.y };
+ let end = { x: this.cache.end.x - scrollOffset.x, y: this.cache.end.y - scrollOffset.y };
+ utils.sendMouseEventToWindow("mousedown", end.x, end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
+ utils.sendMouseEventToWindow("mouseup", end.x, end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
} else {
- this.cache.start.x = json.x - scrollOffset.x;
- this.cache.start.y = json.y - scrollOffset.y;
- utils.sendMouseEventToWindow("mousedown", this.cache.start.x, this.cache.start.y, 0, 1, 0, true);
- // Don't cause a click. A mousedown is enough to move the caret
- //utils.sendMouseEventToWindow("mouseup", this.cache.start.x, this.cache.start.y, 0, 1, 0, true);
- utils.sendMouseEventToWindow("mousedown", this.cache.end.x, this.cache.end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
- utils.sendMouseEventToWindow("mouseup", this.cache.end.x, this.cache.end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
+ // Keep the cache in "client" coordinates, but translate for the mouse event
+ this.cache.start = { x: json.x, y: json.y };
+ let start = { x: this.cache.start.x - scrollOffset.x, y: this.cache.start.y - scrollOffset.y };
+ let end = { x: this.cache.end.x - scrollOffset.x, y: this.cache.end.y - scrollOffset.y };
+
+ utils.sendMouseEventToWindow("mousedown", start.x, start.y, 0, 0, 0, true);
+ utils.sendMouseEventToWindow("mouseup", start.x, start.y, 0, 0, 0, true);
+
+ utils.sendMouseEventToWindow("mousedown", end.x, end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
+ utils.sendMouseEventToWindow("mouseup", end.x, end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
}
// Cache the selected text since the selection might be gone by the time we get the "end" message
let selection = this.contentWindow.getSelection()
this.selectedText = selection.toString().trim();
// Update the rect we use to test when finishing the clipboard operation
let range = selection.getRangeAt(0).QueryInterface(Ci.nsIDOMNSRange);
@@ -1482,16 +1487,22 @@ var SelectionHandler = {
for (let i=0; i<rects.length; i++) {
if (i == 0) {
cache.start.x = rects[i].left + aOffset.x;
cache.start.y = rects[i].bottom + aOffset.y;
}
cache.end.x = rects[i].right + aOffset.x;
cache.end.y = rects[i].bottom + aOffset.y;
}
+
+ // Keep the handles from being positioned completely out of the selection range
+ const HANDLE_VERTICAL_MARGIN = 4;
+ cache.start.y -= HANDLE_VERTICAL_MARGIN;
+ cache.end.y -= HANDLE_VERTICAL_MARGIN;
+
cache.rect = aRange.getBoundingClientRect();
cache.rect.left += aOffset.x;
cache.rect.top += aOffset.y;
cache.rect.right += aOffset.x;
cache.rect.bottom += aOffset.y;
cache.offset = aOffset;
return cache;