This commit is contained in:
Tim Taubert 2012-01-25 17:54:52 +01:00
Родитель efc36914b1 a8e3578994
Коммит a21903df5c
17 изменённых файлов: 210 добавлений и 350 удалений

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

@ -141,7 +141,7 @@ TreePanel.prototype = {
this.treeLoaded = true; this.treeLoaded = true;
this.treeIFrame.addEventListener("click", this.onTreeClick.bind(this), false); this.treeIFrame.addEventListener("click", this.onTreeClick.bind(this), false);
this.treeIFrame.addEventListener("dblclick", this.onTreeDblClick.bind(this), false); this.treeIFrame.addEventListener("dblclick", this.onTreeDblClick.bind(this), false);
this.treeIFrame.addEventListener("keypress", this.IUI, false); this.treeIFrame.focus();
delete this.initializingTreePanel; delete this.initializingTreePanel;
Services.obs.notifyObservers(null, Services.obs.notifyObservers(null,
this.IUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY, null); this.IUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY, null);
@ -466,9 +466,6 @@ TreePanel.prototype = {
editorInput.value = aAttrVal; editorInput.value = aAttrVal;
editorInput.select(); editorInput.select();
// remove tree key navigation events
this.treeIFrame.removeEventListener("keypress", this.IUI, false);
// listen for editor specific events // listen for editor specific events
this.bindEditorEvent(editor, "click", function(aEvent) { this.bindEditorEvent(editor, "click", function(aEvent) {
aEvent.stopPropagation(); aEvent.stopPropagation();
@ -561,9 +558,6 @@ TreePanel.prototype = {
this.editingContext = null; this.editingContext = null;
this.editingEvents = {}; this.editingEvents = {};
// re-add navigation listener
this.treeIFrame.addEventListener("keypress", this.IUI, false);
// event notification // event notification
Services.obs.notifyObservers(null, this.IUI.INSPECTOR_NOTIFICATIONS.EDITOR_CLOSED, Services.obs.notifyObservers(null, this.IUI.INSPECTOR_NOTIFICATIONS.EDITOR_CLOSED,
null); null);
@ -700,7 +694,6 @@ TreePanel.prototype = {
} }
if (this.treeIFrame) { if (this.treeIFrame) {
this.treeIFrame.removeEventListener("keypress", this.IUI, false);
this.treeIFrame.removeEventListener("dblclick", this.onTreeDblClick, false); this.treeIFrame.removeEventListener("dblclick", this.onTreeDblClick, false);
this.treeIFrame.removeEventListener("click", this.onTreeClick, false); this.treeIFrame.removeEventListener("click", this.onTreeClick, false);
let parent = this.treeIFrame.parentNode; let parent = this.treeIFrame.parentNode;

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

@ -756,69 +756,6 @@ Highlighter.prototype = {
aEvent.preventDefault(); aEvent.preventDefault();
aEvent.stopPropagation(); aEvent.stopPropagation();
break; break;
case this.chromeWin.KeyEvent.DOM_VK_LEFT:
let node;
if (this.node) {
node = this.node.parentNode;
} else {
node = this.defaultSelection;
}
if (node && this.isNodeHighlightable(node)) {
this.highlight(node);
}
aEvent.preventDefault();
aEvent.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_RIGHT:
if (this.node) {
// Find the first child that is highlightable.
for (let i = 0; i < this.node.childNodes.length; i++) {
node = this.node.childNodes[i];
if (node && this.isNodeHighlightable(node)) {
break;
}
}
} else {
node = this.defaultSelection;
}
if (node && this.isNodeHighlightable(node)) {
this.highlight(node, true);
}
aEvent.preventDefault();
aEvent.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_UP:
if (this.node) {
// Find a previous sibling that is highlightable.
node = this.node.previousSibling;
while (node && !this.isNodeHighlightable(node)) {
node = node.previousSibling;
}
} else {
node = this.defaultSelection;
}
if (node && this.isNodeHighlightable(node)) {
this.highlight(node, true);
}
aEvent.preventDefault();
aEvent.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_DOWN:
if (this.node) {
// Find a next sibling that is highlightable.
node = this.node.nextSibling;
while (node && !this.isNodeHighlightable(node)) {
node = node.nextSibling;
}
} else {
node = this.defaultSelection;
}
if (node && this.isNodeHighlightable(node)) {
this.highlight(node, true);
}
aEvent.preventDefault();
aEvent.stopPropagation();
break;
} }
} }
}, },

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

@ -286,6 +286,8 @@ InspectorUI.prototype = {
// initialize the highlighter // initialize the highlighter
this.highlighter = new Highlighter(this.chromeWin); this.highlighter = new Highlighter(this.chromeWin);
this.setupNavigationKeys();
this.highlighterReady(); this.highlighterReady();
}, },
@ -349,6 +351,36 @@ InspectorUI.prototype = {
} }
}, },
/**
* Browse nodes according to the breadcrumbs layout, only for some specific
* elements of the UI.
*/
setupNavigationKeys: function IUI_setupNavigationKeys()
{
// UI elements that are arrow keys sensitive:
// - highlighter veil;
// - content window (when the highlighter `veil is pointer-events:none`;
// - the Inspector toolbar.
this.onKeypress = this.onKeypress.bind(this);
this.highlighter.highlighterContainer.addEventListener("keypress",
this.onKeypress, true);
this.win.addEventListener("keypress", this.onKeypress, true);
this.toolbar.addEventListener("keypress", this.onKeypress, true);
},
/**
* Remove the event listeners for the arrowkeys.
*/
removeNavigationKeys: function IUI_removeNavigationKeys()
{
this.highlighter.highlighterContainer.removeEventListener("keypress",
this.onKeypress, true);
this.win.removeEventListener("keypress", this.onKeypress, true);
this.toolbar.removeEventListener("keypress", this.onKeypress, true);
},
/** /**
* Close inspector UI and associated panels. Unhighlight and stop inspecting. * Close inspector UI and associated panels. Unhighlight and stop inspecting.
* Remove event listeners for document scrolling, resize, * Remove event listeners for document scrolling, resize,
@ -375,6 +407,8 @@ InspectorUI.prototype = {
this.closing = true; this.closing = true;
this.toolbar.hidden = true; this.toolbar.hidden = true;
this.removeNavigationKeys();
this.progressListener.destroy(); this.progressListener.destroy();
delete this.progressListener; delete this.progressListener;
@ -592,6 +626,14 @@ InspectorUI.prototype = {
false); false);
} }
break; break;
case "keypress":
switch (event.keyCode) {
case this.chromeWin.KeyEvent.DOM_VK_ESCAPE:
this.closeInspectorUI(false);
event.preventDefault();
event.stopPropagation();
break;
}
case "pagehide": case "pagehide":
win = event.originalTarget.defaultView; win = event.originalTarget.defaultView;
// Skip iframes/frames. // Skip iframes/frames.
@ -611,18 +653,66 @@ InspectorUI.prototype = {
false); false);
} }
break; break;
case "keypress": }
switch (event.keyCode) { },
case this.chromeWin.KeyEvent.DOM_VK_ESCAPE:
this.closeInspectorUI(false); /*
event.preventDefault(); * handles "keypress" events.
event.stopPropagation(); */
break; onKeypress: function IUI_onKeypress(event)
{
let node = null;
let bc = this.breadcrumbs;
switch (event.keyCode) {
case this.chromeWin.KeyEvent.DOM_VK_LEFT:
if (bc.currentIndex != 0)
node = bc.nodeHierarchy[bc.currentIndex - 1].node;
if (node && this.highlighter.isNodeHighlightable(node))
this.highlighter.highlight(node);
event.preventDefault();
event.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_RIGHT:
if (bc.currentIndex < bc.nodeHierarchy.length - 1)
node = bc.nodeHierarchy[bc.currentIndex + 1].node;
if (node && this.highlighter.isNodeHighlightable(node)) {
this.highlighter.highlight(node);
} }
event.preventDefault();
event.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_UP:
if (this.selection) {
// Find a previous sibling that is highlightable.
node = this.selection.previousSibling;
while (node && !this.highlighter.isNodeHighlightable(node)) {
node = node.previousSibling;
}
}
if (node && this.highlighter.isNodeHighlightable(node)) {
this.highlighter.highlight(node, true);
}
event.preventDefault();
event.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_DOWN:
if (this.selection) {
// Find a next sibling that is highlightable.
node = this.selection.nextSibling;
while (node && !this.highlighter.isNodeHighlightable(node)) {
node = node.nextSibling;
}
}
if (node && this.highlighter.isNodeHighlightable(node)) {
this.highlighter.highlight(node, true);
}
event.preventDefault();
event.stopPropagation();
break; break;
} }
}, },
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
//// CssRuleView methods //// CssRuleView methods
@ -1720,6 +1810,8 @@ HTMLBreadcrumbs.prototype = {
} }
if (aIdx > -1) { if (aIdx > -1) {
this.nodeHierarchy[aIdx].button.setAttribute("checked", "true"); this.nodeHierarchy[aIdx].button.setAttribute("checked", "true");
if (this.hadFocus)
this.nodeHierarchy[aIdx].button.focus();
} }
this.currentIndex = aIdx; this.currentIndex = aIdx;
}, },
@ -1895,6 +1987,10 @@ HTMLBreadcrumbs.prototype = {
{ {
this.menu.hidePopup(); this.menu.hidePopup();
let cmdDispatcher = this.IUI.chromeDoc.commandDispatcher;
this.hadFocus = (cmdDispatcher.focusedElement &&
cmdDispatcher.focusedElement.parentNode == this.container);
let selection = this.IUI.selection; let selection = this.IUI.selection;
let idx = this.indexOf(selection); let idx = this.indexOf(selection);
@ -1924,7 +2020,8 @@ HTMLBreadcrumbs.prototype = {
// Make sure the selected node and its neighbours are visible. // Make sure the selected node and its neighbours are visible.
this.scroll(); this.scroll();
} },
} }
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////

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

@ -69,11 +69,6 @@ function SplitView(aRoot)
this._mql = aRoot.ownerDocument.defaultView.matchMedia(LANDSCAPE_MEDIA_QUERY); this._mql = aRoot.ownerDocument.defaultView.matchMedia(LANDSCAPE_MEDIA_QUERY);
this._filter = aRoot.querySelector(".splitview-filter");
if (this._filter) {
this._setupFilterBox();
}
// items list focus and search-on-type handling // items list focus and search-on-type handling
this._nav.addEventListener("keydown", function onKeyCatchAll(aEvent) { this._nav.addEventListener("keydown", function onKeyCatchAll(aEvent) {
function getFocusedItemWithin(nav) { function getFocusedItemWithin(nav) {
@ -116,13 +111,6 @@ function SplitView(aRoot)
} }
return false; return false;
} }
// search-on-type when any non-whitespace character is pressed while list
// has the focus
if (this._filter &&
!/\s/.test(String.fromCharCode(aEvent.which))) {
this._filter.focus();
}
}.bind(this), false); }.bind(this), false);
} }
@ -227,10 +215,6 @@ SplitView.prototype = {
* Called when the item is hidden/inactive. * Called when the item is hidden/inactive.
* - function(summary, details, data) onDestroy * - function(summary, details, data) onDestroy
* Called when the item has been removed. * Called when the item has been removed.
* - function(summary, details, data, query) onFilterBy
* Called when the user performs a filtering search.
* If the function returns false, the item does not match query
* string and will be hidden.
* - object data * - object data
* Object to pass to the callbacks above. * Object to pass to the callbacks above.
* - number ordinal * - number ordinal
@ -327,71 +311,6 @@ SplitView.prototype = {
} }
}, },
/**
* Filter items by given string.
* Matching is performed on every item by calling onFilterBy when defined
* and then by searching aQuery in the summary element's text item.
* Non-matching item is hidden.
*
* If no item matches, 'splitview-all-filtered' class is set on the filter
* input element and the splitview-nav element.
*
* @param string aQuery
* The query string. Use null to reset (no filter).
* @return number
* The number of filtered (non-matching) item.
*/
filterItemsBy: function ASV_filterItemsBy(aQuery)
{
if (!this._nav.hasChildNodes()) {
return 0;
}
if (aQuery) {
aQuery = aQuery.trim();
}
if (!aQuery) {
for (let i = 0; i < this._nav.childNodes.length; ++i) {
this._nav.childNodes[i].classList.remove("splitview-filtered");
}
this._filter.classList.remove("splitview-all-filtered");
this._nav.classList.remove("splitview-all-filtered");
return 0;
}
let count = 0;
let filteredCount = 0;
for (let i = 0; i < this._nav.childNodes.length; ++i) {
let summary = this._nav.childNodes[i];
let matches = false;
let binding = summary.getUserData(BINDING_USERDATA);
if (binding.onFilterBy) {
matches = binding.onFilterBy(summary, binding._details, binding.data, aQuery);
}
if (!matches) { // try text content
let content = summary.textContent.toUpperCase();
matches = (content.indexOf(aQuery.toUpperCase()) > -1);
}
count++;
if (!matches) {
summary.classList.add("splitview-filtered");
filteredCount++;
} else {
summary.classList.remove("splitview-filtered");
}
}
if (count > 0 && filteredCount == count) {
this._filter.classList.add("splitview-all-filtered");
this._nav.classList.add("splitview-all-filtered");
} else {
this._filter.classList.remove("splitview-all-filtered");
this._nav.classList.remove("splitview-all-filtered");
}
return filteredCount;
},
/** /**
* Set the item's CSS class name. * Set the item's CSS class name.
* This sets the class on both the summary and details elements, retaining * This sets the class on both the summary and details elements, retaining
@ -415,39 +334,4 @@ SplitView.prototype = {
viewSpecific = viewSpecific ? viewSpecific.join(" ") : ""; viewSpecific = viewSpecific ? viewSpecific.join(" ") : "";
binding._details.className = viewSpecific + " " + aClassName; binding._details.className = viewSpecific + " " + aClassName;
}, },
/**
* Set up filter search box.
*/
_setupFilterBox: function ASV__setupFilterBox()
{
let clearFilter = function clearFilter(aEvent) {
this._filter.value = "";
this.filterItemsBy("");
return false;
}.bind(this);
this._filter.addEventListener("command", function onFilterInput(aEvent) {
this.filterItemsBy(this._filter.value);
}.bind(this), false);
this._filter.addEventListener("keyup", function onFilterKeyUp(aEvent) {
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
clearFilter();
}
if (aEvent.keyCode == aEvent.DOM_VK_ENTER ||
aEvent.keyCode == aEvent.DOM_VK_RETURN) {
// autofocus matching item if there is only one
let matches = this._nav.querySelectorAll("* > li:not(.splitview-filtered)");
if (matches.length == 1) {
this.activeSummary = matches[0];
}
}
}.bind(this), false);
let clearButtons = this._root.querySelectorAll(".splitview-filter-clearButton");
for (let i = 0; i < clearButtons.length; ++i) {
clearButtons[i].addEventListener("click", clearFilter, false);
}
}
}; };

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

@ -58,6 +58,7 @@ box,
.splitview-controller { .splitview-controller {
min-height: 3em; min-height: 3em;
max-height: 14em; max-height: 14em;
max-width: 400px;
} }
.splitview-nav { .splitview-nav {
@ -123,4 +124,8 @@ ol.splitview-nav > li.splitview-filtered {
.splitview-portrait-resizer { .splitview-portrait-resizer {
display: -moz-box; display: -moz-box;
} }
.splitview-controller {
max-width: none;
}
} }

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

@ -15,6 +15,8 @@ Orion version: git clone from 2011-12-09
see https://bugs.eclipse.org/bugs/show_bug.cgi?id=366312 see https://bugs.eclipse.org/bugs/show_bug.cgi?id=366312
+ patch for Mozilla Bug 711737 - Orion should support all the CSS properties from CSS1, CSS2, CSS2.1 and CSS3 + patch for Mozilla Bug 711737 - Orion should support all the CSS properties from CSS1, CSS2, CSS2.1 and CSS3
https://bugzilla.mozilla.org/show_bug.cgi?id=711737 https://bugzilla.mozilla.org/show_bug.cgi?id=711737
+ patch for Mozilla Bug 719028 - Style Editor does not highlight a few CSS2.0 and CSS3 properties
https://bugzilla.mozilla.org/show_bug.cgi?id=719028
# License # License

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

@ -10,6 +10,7 @@
* Felipe Heidrich (IBM Corporation) - initial API and implementation * Felipe Heidrich (IBM Corporation) - initial API and implementation
* Silenio Quarti (IBM Corporation) - initial API and implementation * Silenio Quarti (IBM Corporation) - initial API and implementation
* Mihai Sucan (Mozilla Foundation) - fix for Bug#364214 * Mihai Sucan (Mozilla Foundation) - fix for Bug#364214
* Alex Lakatos (Mozilla Contributor) - fix for Mozilla Bug#719028
*/ */
/*global window */ /*global window */
@ -10488,13 +10489,14 @@ define(['orion/textview/annotations'], function(mAnnotations) {
"column-rule-color", "column-rule-style", "column-rule-width", "column-span", "column-width", "columns", "content", "counter-increment", "column-rule-color", "column-rule-style", "column-rule-width", "column-span", "column-width", "columns", "content", "counter-increment",
"counter-reset", "crop", "cue", "cue-after", "cue-before", "cursor", "direction", "display", "dominant-baseline", "counter-reset", "crop", "cue", "cue-after", "cue-before", "cursor", "direction", "display", "dominant-baseline",
"drop-initial-after-adjust", "drop-initial-after-align", "drop-initial-before-adjust", "drop-initial-before-align", "drop-initial-size", "drop-initial-after-adjust", "drop-initial-after-align", "drop-initial-before-adjust", "drop-initial-before-align", "drop-initial-size",
"drop-initial-value", "elevation", "empty-cells", "fit", "fit-position", "float", "float-offset", "font", "font-family", "font-size", "drop-initial-value", "elevation", "empty-cells", "fit", "fit-position", "flex-align", "flex-flow", "flex-inline-pack", "flex-order",
"font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "grid-columns", "grid-rows", "hanging-punctuation", "flex-pack", "float", "float-offset", "font", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style",
"height", "hyphenate-after", "hyphenate-before", "hyphenate-character", "hyphenate-lines", "hyphenate-resource", "hyphens", "icon", "font-variant", "font-weight", "grid-columns", "grid-rows", "hanging-punctuation", "height", "hyphenate-after",
"image-orientation", "image-rendering", "image-resolution", "inline-box-align", "left", "letter-spacing", "line-height", "hyphenate-before", "hyphenate-character", "hyphenate-lines", "hyphenate-resource", "hyphens", "icon", "image-orientation",
"line-stacking", "line-stacking-ruby", "line-stacking-shift", "line-stacking-strategy", "list-style", "list-style-image", "image-rendering", "image-resolution", "inline-box-align", "left", "letter-spacing", "line-height", "line-stacking",
"list-style-position", "list-style-type", "margin", "margin-bottom", "margin-left", "margin-right", "margin-top", "mark", "mark-after", "line-stacking-ruby", "line-stacking-shift", "line-stacking-strategy", "list-style", "list-style-image", "list-style-position",
"mark-before", "marks", "marquee-direction", "marquee-loop", "marquee-play-count", "marquee-speed", "marquee-style", "max-height", "list-style-type", "margin", "margin-bottom", "margin-left", "margin-right", "margin-top", "mark", "mark-after", "mark-before",
"marker-offset", "marks", "marquee-direction", "marquee-loop", "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
"max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", "nav-left", "nav-right", "nav-up", "opacity", "orphans", "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", "nav-left", "nav-right", "nav-up", "opacity", "orphans",
"outline", "outline-color", "outline-offset", "outline-style", "outline-width", "overflow", "overflow-style", "overflow-x", "outline", "outline-color", "outline-offset", "outline-style", "outline-width", "overflow", "overflow-style", "overflow-x",
"overflow-y", "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", "page", "page-break-after", "page-break-before", "overflow-y", "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", "page", "page-break-after", "page-break-before",

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

@ -229,6 +229,8 @@ StyleEditor.prototype = {
}; };
sourceEditor.init(aElement, config, function onSourceEditorReady() { sourceEditor.init(aElement, config, function onSourceEditorReady() {
setupBracketCompletion(sourceEditor);
sourceEditor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, sourceEditor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED,
function onTextChanged(aEvent) { function onTextChanged(aEvent) {
this.updateStyleSheet(); this.updateStyleSheet();
@ -1132,3 +1134,48 @@ function repeat(aText, aCount)
{ {
return (new Array(aCount + 1)).join(aText); return (new Array(aCount + 1)).join(aText);
} }
/**
* Set up bracket completion on a given SourceEditor.
* This automatically closes the following CSS brackets: "{", "(", "["
*
* @param SourceEditor aSourceEditor
*/
function setupBracketCompletion(aSourceEditor)
{
let editorElement = aSourceEditor.editorElement;
let pairs = {
123: { // {
closeString: "}",
closeKeyCode: Ci.nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET
},
40: { // (
closeString: ")",
closeKeyCode: Ci.nsIDOMKeyEvent.DOM_VK_0
},
91: { // [
closeString: "]",
closeKeyCode: Ci.nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET
},
};
editorElement.addEventListener("keypress", function onKeyPress(aEvent) {
let pair = pairs[aEvent.charCode];
if (!pair) {
return true;
}
// We detected an open bracket, sending closing character
let keyCode = pair.closeKeyCode;
let charCode = pair.closeString.charCodeAt(0);
let modifiers = 0;
let utils = editorElement.ownerDocument.defaultView.
QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
let handled = utils.sendKeyEvent("keydown", keyCode, 0, modifiers);
utils.sendKeyEvent("keypress", 0, charCode, modifiers, !handled);
utils.sendKeyEvent("keyup", keyCode, 0, modifiers);
// and rewind caret
aSourceEditor.setCaretOffset(aSourceEditor.getCaretOffset() - 1);
}, false);
}

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

@ -402,7 +402,9 @@ StyleEditorChrome.prototype = {
this._view.setItemClassName(summary, aEditor.flags); this._view.setItemClassName(summary, aEditor.flags);
text(summary, ".stylesheet-name", aEditor.getFriendlyName()); let label = summary.querySelector(".stylesheet-name > label");
label.setAttribute("value", aEditor.getFriendlyName());
text(summary, ".stylesheet-title", aEditor.styleSheet.title || ""); text(summary, ".stylesheet-title", aEditor.styleSheet.title || "");
text(summary, ".stylesheet-rule-count", text(summary, ".stylesheet-rule-count",
PluralForm.get(ruleCount, _("ruleCount.label")).replace("#1", ruleCount)); PluralForm.get(ruleCount, _("ruleCount.label")).replace("#1", ruleCount));

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

@ -20,6 +20,7 @@
* *
* Contributor(s): * Contributor(s):
* Cedric Vivier <cedricv@neonux.com> (original author) * Cedric Vivier <cedricv@neonux.com> (original author)
* Paul Rouget <paul@mozilla.com>
* *
* Alternatively, the contents of this file may be used under the terms of * 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 * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -64,22 +65,17 @@ li.error > .stylesheet-info > .stylesheet-more > .stylesheet-error-message {
} }
.stylesheet-name { .stylesheet-name {
/* clip the text at the beginning */ outline: none;
display: -moz-box; }
direction: rtl;
text-align: left; .stylesheet-name > label {
overflow: hidden; cursor: pointer;
} }
.splitview-nav > li > hgroup.stylesheet-info { .splitview-nav > li > hgroup.stylesheet-info {
-moz-box-pack: center; -moz-box-pack: center;
} }
.splitview-nav:-moz-locale-dir(ltr) > li.unsaved > hgroup .stylesheet-name:before,
.splitview-nav:-moz-locale-dir(rtl) > li.unsaved > hgroup .stylesheet-name:after {
content: "* ";
}
.stylesheet-enabled { .stylesheet-enabled {
display: -moz-box; display: -moz-box;
} }
@ -107,7 +103,7 @@ li:hover > hgroup > .stylesheet-more > h3 > .stylesheet-saveButton {
.stylesheet-more { .stylesheet-more {
-moz-box-flex: 1; -moz-box-flex: 1;
-moz-box-direction: reverse; -moz-box-pack: end;
} }
.splitview-nav > li > hgroup.stylesheet-info { .splitview-nav > li > hgroup.stylesheet-info {

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

@ -54,8 +54,19 @@
persist="screenX screenY width height sizemode"> persist="screenX screenY width height sizemode">
<xul:script type="application/javascript" src="chrome://global/content/globalOverlay.js"/> <xul:script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
<xul:commandset id="style-editor-commandset">
<xul:command id="style-editor-cmd-close" oncommand="window.close();"/>
</xul:commandset>
<xul:keyset id="style-editor-keyset">
<xul:key id="style-editor-key-close"
key="&closeCmd.key;"
command="style-editor-cmd-close"
modifiers="accel"/>
</xul:keyset>
<xul:box id="style-editor-chrome" class="splitview-root loading"> <xul:box id="style-editor-chrome" class="splitview-root loading">
<xul:box class="splitview-controller" id="stylesheets-controller" persist="width height"> <xul:box class="splitview-controller">
<xul:box class="splitview-main"> <xul:box class="splitview-main">
<xul:toolbar class="devtools-toolbar"> <xul:toolbar class="devtools-toolbar">
<xul:toolbarbutton class="style-editor-newButton devtools-toolbarbutton" <xul:toolbarbutton class="style-editor-newButton devtools-toolbarbutton"
@ -68,14 +79,10 @@
tooltiptext="&importButton.tooltip;" tooltiptext="&importButton.tooltip;"
label="&importButton.label;" label="&importButton.label;"
disabled="true"/> disabled="true"/>
<xul:spacer flex="1"/>
<xul:textbox class="splitview-filter devtools-searchinput"
type="search" flex="1"
tooltiptext="&searchInput.tooltip;"
placeholder="&searchInput.placeholder;"/>
</xul:toolbar> </xul:toolbar>
</xul:box> </xul:box>
<xul:box class="splitview-nav-container"> <xul:box id="splitview-resizer-target" class="splitview-nav-container"
persist="width height">
<ol class="splitview-nav" tabindex="0"></ol> <ol class="splitview-nav" tabindex="0"></ol>
<div class="splitview-nav placeholder empty"> <div class="splitview-nav placeholder empty">
<p><strong>&noStyleSheet.label;</strong></p> <p><strong>&noStyleSheet.label;</strong></p>
@ -84,13 +91,6 @@
class="style-editor-newButton">&noStyleSheet-tip-action.label;</a> class="style-editor-newButton">&noStyleSheet-tip-action.label;</a>
&noStyleSheet-tip-end.label;</p> &noStyleSheet-tip-end.label;</p>
</div> </div>
<div class="splitview-nav placeholder all-filtered">
<p><strong>&searchNoResults.label;</strong></p>
<p>
<a href="#"
class="splitview-filter-clearButton">&searchClearButton.label;</a>
</p>
</div>
</xul:box> <!-- .splitview-nav-container --> </xul:box> <!-- .splitview-nav-container -->
</xul:box> <!-- .splitview-controller --> </xul:box> <!-- .splitview-controller -->
<xul:box class="splitview-side-details"/> <xul:box class="splitview-side-details"/>
@ -101,7 +101,7 @@
title="&visibilityToggle.tooltip;" title="&visibilityToggle.tooltip;"
accesskey="&saveButton.accesskey;"></a> accesskey="&saveButton.accesskey;"></a>
<hgroup class="stylesheet-info"> <hgroup class="stylesheet-info">
<h1><a class="stylesheet-name" href="#"></a></h1> <h1><a class="stylesheet-name" href="#"><xul:label crop="start"/></a></h1>
<div class="stylesheet-more"> <div class="stylesheet-more">
<h3 class="stylesheet-title"></h3> <h3 class="stylesheet-title"></h3>
<h3 class="stylesheet-rule-count"></h3> <h3 class="stylesheet-rule-count"></h3>
@ -116,12 +116,12 @@
<xul:box id="splitview-tpl-details-stylesheet" class="splitview-details"> <xul:box id="splitview-tpl-details-stylesheet" class="splitview-details">
<xul:resizer class="splitview-portrait-resizer" <xul:resizer class="splitview-portrait-resizer"
dir="bottom" dir="bottom"
element="stylesheets-controller"/> element="splitview-resizer-target"/>
<xul:toolbar id="splitview-details-toolbar" class="devtools-toolbar"> <xul:toolbar id="splitview-details-toolbar" class="devtools-toolbar">
<xul:resizer class="splitview-landscape-resizer" <xul:resizer class="splitview-landscape-resizer"
dir="bottomend" dir="bottomend"
element="stylesheets-controller"/> element="splitview-resizer-target"/>
</xul:toolbar> </xul:toolbar>
<xul:box class="stylesheet-editor-input textbox" <xul:box class="stylesheet-editor-input textbox"
data-placeholder="&editorTextbox.placeholder;"/> data-placeholder="&editorTextbox.placeholder;"/>

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

@ -53,7 +53,6 @@ _BROWSER_TEST_FILES = \
browser_styleeditor_pretty.js \ browser_styleeditor_pretty.js \
browser_styleeditor_readonly.js \ browser_styleeditor_readonly.js \
browser_styleeditor_reopen.js \ browser_styleeditor_reopen.js \
browser_styleeditor_sv_filter.js \
browser_styleeditor_sv_keynav.js \ browser_styleeditor_sv_keynav.js \
browser_styleeditor_sv_resize.js \ browser_styleeditor_sv_resize.js \
four.html \ four.html \

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

@ -85,7 +85,7 @@ function testFirstStyleSheetEditor(aChrome, aEditor)
ok(!summary.classList.contains("inline"), ok(!summary.classList.contains("inline"),
"first stylesheet UI does not have INLINE class"); "first stylesheet UI does not have INLINE class");
let name = summary.querySelector(".stylesheet-name").textContent; let name = summary.querySelector(".stylesheet-name > label").getAttribute("value");
is(name, "simple.css", is(name, "simple.css",
"first stylesheet's name is `simple.css`"); "first stylesheet's name is `simple.css`");
@ -113,7 +113,7 @@ function testSecondStyleSheetEditor(aChrome, aEditor)
ok(summary.classList.contains("inline"), ok(summary.classList.contains("inline"),
"second stylesheet UI has INLINE class"); "second stylesheet UI has INLINE class");
let name = summary.querySelector(".stylesheet-name").textContent; let name = summary.querySelector(".stylesheet-name > label").getAttribute("value");
ok(/^<.*>$/.test(name), ok(/^<.*>$/.test(name),
"second stylesheet's name is surrounded by `<>`"); "second stylesheet's name is surrounded by `<>`");

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

@ -5,7 +5,7 @@
const TESTCASE_URI = TEST_BASE + "simple.html"; const TESTCASE_URI = TEST_BASE + "simple.html";
const TRANSITION_CLASS = "moz-styleeditor-transitioning"; const TRANSITION_CLASS = "moz-styleeditor-transitioning";
const TESTCASE_CSS_SOURCE = "body{background-color:red;";
function test() function test()
{ {
@ -79,9 +79,13 @@ function testEditorAdded(aChrome, aEditor)
is(computedStyle.backgroundColor, "rgb(255, 255, 255)", is(computedStyle.backgroundColor, "rgb(255, 255, 255)",
"content's background color is initially white"); "content's background color is initially white");
for each (let c in "body{background-color:red;}") { for each (let c in TESTCASE_CSS_SOURCE) {
EventUtils.synthesizeKey(c, {}, gChromeWindow); EventUtils.synthesizeKey(c, {}, gChromeWindow);
} }
is(aEditor.sourceEditor.getText(), TESTCASE_CSS_SOURCE + "}",
"rule bracket has been auto-closed");
}, gChromeWindow) ; }, gChromeWindow) ;
}, },

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

@ -1,101 +0,0 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const TESTCASE_URI = TEST_BASE + "simple.html";
function test()
{
waitForExplicitFinish();
addTabAndLaunchStyleEditorChromeWhenLoaded(function (aChrome) {
aChrome.addChromeListener({
onContentAttach: run
});
if (aChrome.isContentAttached) {
run(aChrome);
}
});
content.location = TESTCASE_URI;
}
function getFilteredItemsCount(nav)
{
let matches = nav.querySelectorAll("*.splitview-filtered");
return matches ? matches.length : 0;
}
function run(aChrome)
{
aChrome.editors[0].addActionListener({onAttach: onFirstEditorAttach});
aChrome.editors[1].addActionListener({onAttach: onSecondEditorAttach});
}
function onFirstEditorAttach(aEditor)
{
let filter = gChromeWindow.document.querySelector(".splitview-filter");
// force the command event on input since it is not possible to disable
// the search textbox's timeout.
let forceCommandEvent = function forceCommandEvent() {
let evt = gChromeWindow.document.createEvent("XULCommandEvent");
evt.initCommandEvent("command", true, true, gChromeWindow, 0, false, false,
false, false, null);
filter.dispatchEvent(evt);
}
filter.addEventListener("input", forceCommandEvent, false);
let nav = gChromeWindow.document.querySelector(".splitview-nav");
nav.focus();
is(getFilteredItemsCount(nav), 0,
"there is 0 filtered item initially");
waitForFocus(function () {
// Search [s] (type-on-search since we focused nav above - not filter directly)
EventUtils.synthesizeKey("s", {}, gChromeWindow);
// the search space is "simple.css" and "inline stylesheet #1" (2 sheets)
is(getFilteredItemsCount(nav), 0,
"there is 0 filtered item if searching for 's'");
EventUtils.synthesizeKey("i", {}, gChromeWindow); // Search [si]
is(getFilteredItemsCount(nav), 1, // inline stylesheet is filtered
"there is 1 filtered item if searching for 's'");
// use uppercase to check that filtering is case-insensitive
EventUtils.synthesizeKey("X", {}, gChromeWindow); // Search [siX]
is(getFilteredItemsCount(nav), 2,
"there is 2 filtered items if searching for 's'"); // no match
// clear the search
EventUtils.synthesizeKey("VK_ESCAPE", {}, gChromeWindow);
is(filter.value, "",
"filter is back to empty");
is(getFilteredItemsCount(nav), 0,
"there is 0 filtered item when filter is empty again");
for each (let c in "inline") {
EventUtils.synthesizeKey(c, {}, gChromeWindow);
}
is(getFilteredItemsCount(nav), 1, // simple.css is filtered
"there is 1 filtered item if searching for 'inline'");
// auto-select the only result (enter the editor)
EventUtils.synthesizeKey("VK_ENTER", {}, gChromeWindow);
filter.removeEventListener("input", forceCommandEvent, false);
}, gChromeWindow);
}
function onSecondEditorAttach(aEditor)
{
ok(aEditor.sourceEditor.hasFocus(),
"second editor has been selected and focused automatically.");
finish();
}

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

@ -1310,6 +1310,7 @@ InplaceEditor.prototype = {
prevent = true; prevent = true;
this.cancelled = true; this.cancelled = true;
this.input.blur(); this.input.blur();
aEvent.stopPropagation();
} else if (aEvent.keyCode === Ci.nsIDOMKeyEvent.DOM_VK_SPACE) { } else if (aEvent.keyCode === Ci.nsIDOMKeyEvent.DOM_VK_SPACE) {
// No need for leading spaces here. This is particularly // No need for leading spaces here. This is particularly
// noticable when adding a property: it's very natural to type // noticable when adding a property: it's very natural to type

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

@ -22,17 +22,6 @@
<!ENTITY importButton.accesskey "I"> <!ENTITY importButton.accesskey "I">
<!ENTITY importButton.commandkey "i"> <!ENTITY importButton.commandkey "i">
<!ENTITY searchInput.tooltip "Filter style sheets by name">
<!ENTITY searchInput.placeholder "Find style sheet">
<!-- LOCALIZATION NOTE (searchNoResults): This is shown when searching a term
that is not found in any stylesheet or stylesheet name. -->
<!ENTITY searchNoResults.label "No matching style sheet has been found.">
<!-- LOCALIZATION NOTE (searchClearButton): This button clears the search input
box and is visible only when a search term has been typed. -->
<!ENTITY searchClearButton.label "Clear">
<!ENTITY visibilityToggle.tooltip "Toggle style sheet visibility"> <!ENTITY visibilityToggle.tooltip "Toggle style sheet visibility">
<!ENTITY visibilityToggle.accesskey "V"> <!ENTITY visibilityToggle.accesskey "V">
@ -60,3 +49,6 @@
<!ENTITY noStyleSheet-tip-action.label "append a new style sheet"> <!ENTITY noStyleSheet-tip-action.label "append a new style sheet">
<!-- LOCALICATION NOTE (noStyleSheet-tip-end.label): End of the tip sentence --> <!-- LOCALICATION NOTE (noStyleSheet-tip-end.label): End of the tip sentence -->
<!ENTITY noStyleSheet-tip-end.label "?"> <!ENTITY noStyleSheet-tip-end.label "?">
<!-- LOCALIZATION NOTE (closeCmd.key): Accel + this key closes the window. -->
<!ENTITY closeCmd.key "W">