mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 808371 - Allow adding new properties to objects in the VariablesView. r=vp, r=jryans
This commit is contained in:
parent
d8d91820da
commit
b04c4c4053
@ -16,6 +16,7 @@ function ManifestEditor(project) {
|
||||
this._onEval = this._onEval.bind(this);
|
||||
this._onSwitch = this._onSwitch.bind(this);
|
||||
this._onDelete = this._onDelete.bind(this);
|
||||
this._onNew = this._onNew.bind(this);
|
||||
}
|
||||
|
||||
ManifestEditor.prototype = {
|
||||
@ -54,6 +55,7 @@ ManifestEditor.prototype = {
|
||||
editor.eval = this._onEval;
|
||||
editor.switch = this._onSwitch;
|
||||
editor.delete = this._onDelete;
|
||||
editor.new = this._onNew;
|
||||
}
|
||||
|
||||
return this.update();
|
||||
@ -87,6 +89,14 @@ ManifestEditor.prototype = {
|
||||
eval(evalString);
|
||||
},
|
||||
|
||||
_onNew: function(variable, newName, newValue) {
|
||||
let manifest = this.manifest;
|
||||
let symbolicName = variable.symbolicName + "['" + newName + "']";
|
||||
let evalString = "manifest" + symbolicName + " = " + newValue + ";";
|
||||
eval(evalString);
|
||||
this.update();
|
||||
},
|
||||
|
||||
update: function() {
|
||||
this.editor.createHierarchy();
|
||||
this.editor.rawObject = this.manifest;
|
||||
|
@ -6,6 +6,9 @@ const {Services} = Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const MANIFEST_EDITOR_ENABLED = "devtools.appmanager.manifestEditor.enabled";
|
||||
|
||||
|
||||
let gManifestWindow, gManifestEditor;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
@ -15,7 +18,14 @@ function test() {
|
||||
yield selectProjectsPanel();
|
||||
yield addSamplePackagedApp();
|
||||
yield showSampleProjectDetails();
|
||||
|
||||
gManifestWindow = getManifestWindow();
|
||||
gManifestEditor = getProjectsWindow().UI.manifestEditor;
|
||||
yield changeManifestValue("name", "the best app");
|
||||
yield addNewManifestProperty("developer", "foo", "bar");
|
||||
gManifestWindow = null;
|
||||
gManifestEditor = null;
|
||||
|
||||
yield removeSamplePackagedApp();
|
||||
yield removeTab(tab);
|
||||
Services.prefs.setBoolPref(MANIFEST_EDITOR_ENABLED, false);
|
||||
@ -23,32 +33,73 @@ function test() {
|
||||
});
|
||||
}
|
||||
|
||||
// Wait until the animation from commitHierarchy has completed
|
||||
function waitForUpdate() {
|
||||
return waitForTime(gManifestEditor.editor.lazyEmptyDelay + 1);
|
||||
}
|
||||
|
||||
function changeManifestValue(key, value) {
|
||||
return Task.spawn(function() {
|
||||
let manifestWindow = getManifestWindow();
|
||||
let manifestEditor = getProjectsWindow().UI.manifestEditor;
|
||||
|
||||
let propElem = manifestWindow.document
|
||||
let propElem = gManifestWindow.document
|
||||
.querySelector("[id ^= '" + key + "']");
|
||||
is(propElem.querySelector(".name").value, key,
|
||||
"Key doesn't match expected value");
|
||||
|
||||
let valueElem = propElem.querySelector(".value");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, valueElem, manifestWindow);
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, valueElem, gManifestWindow);
|
||||
|
||||
let valueInput = propElem.querySelector(".element-value-input");
|
||||
valueInput.value = '"' + value + '"';
|
||||
EventUtils.sendKey("RETURN", manifestWindow);
|
||||
EventUtils.sendKey("RETURN", gManifestWindow);
|
||||
|
||||
// Wait until the animation from commitHierarchy has completed
|
||||
yield waitForTime(manifestEditor.editor.lazyEmptyDelay + 1);
|
||||
yield waitForUpdate();
|
||||
// Elements have all been replaced, re-select them
|
||||
propElem = manifestWindow.document.querySelector("[id ^= '" + key + "']");
|
||||
propElem = gManifestWindow.document.querySelector("[id ^= '" + key + "']");
|
||||
valueElem = propElem.querySelector(".value");
|
||||
is(valueElem.value, '"' + value + '"',
|
||||
"Value doesn't match expected value");
|
||||
|
||||
is(manifestEditor.manifest[key], value,
|
||||
is(gManifestEditor.manifest[key], value,
|
||||
"Manifest doesn't contain expected value");
|
||||
});
|
||||
}
|
||||
|
||||
function addNewManifestProperty(parent, key, value) {
|
||||
return Task.spawn(function() {
|
||||
let parentElem = gManifestWindow.document
|
||||
.querySelector("[id ^= '" + parent + "']");
|
||||
ok(parentElem,
|
||||
"Found parent element");
|
||||
let addPropertyElem = parentElem
|
||||
.querySelector(".variables-view-add-property");
|
||||
ok(addPropertyElem,
|
||||
"Found add-property button");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, addPropertyElem, gManifestWindow);
|
||||
|
||||
let nameInput = parentElem.querySelector(".element-name-input");
|
||||
nameInput.value = key;
|
||||
EventUtils.sendKey("TAB", gManifestWindow);
|
||||
|
||||
let valueInput = parentElem.querySelector(".element-value-input");
|
||||
valueInput.value = '"' + value + '"';
|
||||
EventUtils.sendKey("RETURN", gManifestWindow);
|
||||
|
||||
yield waitForUpdate();
|
||||
|
||||
let newElem = gManifestWindow.document.querySelector("[id ^= '" + key + "']");
|
||||
let nameElem = newElem.querySelector(".name");
|
||||
is(nameElem.value, key,
|
||||
"Key doesn't match expected Key");
|
||||
|
||||
ok(key in gManifestEditor.manifest[parent],
|
||||
"Manifest doesn't contain expected key");
|
||||
|
||||
let valueElem = newElem.querySelector(".value");
|
||||
is(valueElem.value, '"' + value + '"',
|
||||
"Value doesn't match expected value");
|
||||
|
||||
is(gManifestEditor.manifest[parent][key], value,
|
||||
"Manifest doesn't contain expected value");
|
||||
});
|
||||
}
|
||||
|
@ -1,3 +1,6 @@
|
||||
{
|
||||
"name": "My packaged app"
|
||||
"name": "My packaged app",
|
||||
"developer": {
|
||||
"name": "Foo Bar"
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,44 @@ function test() {
|
||||
is(testVar.get("someProp4").target.querySelector(".value").getAttribute("value"), "Object",
|
||||
"The grip information for the variable wasn't set correctly (9).");
|
||||
|
||||
let parent = testVar.get("someProp2");
|
||||
let child = parent.addItem("child", {
|
||||
value: {
|
||||
type: "null"
|
||||
}
|
||||
});
|
||||
|
||||
is(variables.getItemForNode(parent.target), parent,
|
||||
"VariablesView should have a record of the parent.");
|
||||
is(variables.getItemForNode(child.target), child,
|
||||
"VariablesView should have a record of the child.");
|
||||
is([...parent].length, 1,
|
||||
"Parent should have one child.");
|
||||
|
||||
parent.remove();
|
||||
|
||||
is(variables.getItemForNode(parent.target), undefined,
|
||||
"VariablesView should not have a record of the parent anymore.");
|
||||
is(parent.target.parentNode, null,
|
||||
"Parent element should not have a parent.")
|
||||
is(variables.getItemForNode(child.target), undefined,
|
||||
"VariablesView should not have a record of the child anymore.");
|
||||
is(child.target.parentNode, null,
|
||||
"Child element should not have a parent.")
|
||||
is([...parent].length, 0,
|
||||
"Parent should have zero children.");
|
||||
|
||||
testScope.remove();
|
||||
|
||||
is([...variables].length, 0,
|
||||
"VariablesView should have been emptied.");
|
||||
is(Cu.nondeterministicGetWeakMapKeys(variables._itemsByElement).length, 0,
|
||||
"VariablesView _itemsByElement map has been emptied.");
|
||||
is(variables._currHierarchy.size, 0,
|
||||
"VariablesView _currHierarchy map has been emptied.");
|
||||
is(variables._list.children.length, 0,
|
||||
"VariablesView element should have no children.");
|
||||
|
||||
closeDebuggerAndFinish(aPanel);
|
||||
});
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ function performTest() {
|
||||
gVariablesView.eval = function() {};
|
||||
gVariablesView.switch = function() {};
|
||||
gVariablesView.delete = function() {};
|
||||
gVariablesView.new = function() {};
|
||||
gVariablesView.rawObject = test;
|
||||
|
||||
testHierarchy();
|
||||
@ -503,8 +504,8 @@ function testAnonymousHeaders(fooScope, anonymousVar, anonymousScope, barVar, ba
|
||||
}
|
||||
|
||||
function testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar, bazProperty) {
|
||||
is(fooScope.preventDisableOnChage, gVariablesView.preventDisableOnChage,
|
||||
"The preventDisableOnChage property should persist from the view to all scopes.");
|
||||
is(fooScope.preventDisableOnChange, gVariablesView.preventDisableOnChange,
|
||||
"The preventDisableOnChange property should persist from the view to all scopes.");
|
||||
is(fooScope.preventDescriptorModifiers, gVariablesView.preventDescriptorModifiers,
|
||||
"The preventDescriptorModifiers property should persist from the view to all scopes.");
|
||||
is(fooScope.editableNameTooltip, gVariablesView.editableNameTooltip,
|
||||
@ -525,13 +526,15 @@ function testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar,
|
||||
"The switch property should persist from the view to all scopes.");
|
||||
is(fooScope.delete, gVariablesView.delete,
|
||||
"The delete property should persist from the view to all scopes.");
|
||||
is(fooScope.new, gVariablesView.new,
|
||||
"The new property should persist from the view to all scopes.");
|
||||
isnot(fooScope.eval, fooScope.switch,
|
||||
"The eval and switch functions got mixed up in the scope.");
|
||||
isnot(fooScope.switch, fooScope.delete,
|
||||
"The eval and switch functions got mixed up in the scope.");
|
||||
|
||||
is(barVar.preventDisableOnChage, gVariablesView.preventDisableOnChage,
|
||||
"The preventDisableOnChage property should persist from the view to all variables.");
|
||||
is(barVar.preventDisableOnChange, gVariablesView.preventDisableOnChange,
|
||||
"The preventDisableOnChange property should persist from the view to all variables.");
|
||||
is(barVar.preventDescriptorModifiers, gVariablesView.preventDescriptorModifiers,
|
||||
"The preventDescriptorModifiers property should persist from the view to all variables.");
|
||||
is(barVar.editableNameTooltip, gVariablesView.editableNameTooltip,
|
||||
@ -552,13 +555,15 @@ function testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar,
|
||||
"The switch property should persist from the view to all variables.");
|
||||
is(barVar.delete, gVariablesView.delete,
|
||||
"The delete property should persist from the view to all variables.");
|
||||
is(barVar.new, gVariablesView.new,
|
||||
"The new property should persist from the view to all variables.");
|
||||
isnot(barVar.eval, barVar.switch,
|
||||
"The eval and switch functions got mixed up in the variable.");
|
||||
isnot(barVar.switch, barVar.delete,
|
||||
"The eval and switch functions got mixed up in the variable.");
|
||||
|
||||
is(bazProperty.preventDisableOnChage, gVariablesView.preventDisableOnChage,
|
||||
"The preventDisableOnChage property should persist from the view to all properties.");
|
||||
is(bazProperty.preventDisableOnChange, gVariablesView.preventDisableOnChange,
|
||||
"The preventDisableOnChange property should persist from the view to all properties.");
|
||||
is(bazProperty.preventDescriptorModifiers, gVariablesView.preventDescriptorModifiers,
|
||||
"The preventDescriptorModifiers property should persist from the view to all properties.");
|
||||
is(bazProperty.editableNameTooltip, gVariablesView.editableNameTooltip,
|
||||
@ -579,6 +584,8 @@ function testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar,
|
||||
"The switch property should persist from the view to all properties.");
|
||||
is(bazProperty.delete, gVariablesView.delete,
|
||||
"The delete property should persist from the view to all properties.");
|
||||
is(bazProperty.new, gVariablesView.new,
|
||||
"The new property should persist from the view to all properties.");
|
||||
isnot(bazProperty.eval, bazProperty.switch,
|
||||
"The eval and switch functions got mixed up in the property.");
|
||||
isnot(bazProperty.switch, bazProperty.delete,
|
||||
|
@ -52,7 +52,7 @@ const GENERIC_VARIABLES_VIEW_SETTINGS = {
|
||||
searchEnabled: true,
|
||||
editableValueTooltip: "",
|
||||
editableNameTooltip: "",
|
||||
preventDisableOnChage: true,
|
||||
preventDisableOnChange: true,
|
||||
preventDescriptorModifiers: true,
|
||||
eval: () => {},
|
||||
switch: () => {}
|
||||
|
@ -263,11 +263,20 @@ VariablesView.prototype = {
|
||||
*/
|
||||
delete: null,
|
||||
|
||||
/**
|
||||
* Function called each time a property is added via user interaction. If
|
||||
* null, then property additions are disabled.
|
||||
*
|
||||
* This property is applied recursively onto each scope in this view and
|
||||
* affects only the child nodes when they're created.
|
||||
*/
|
||||
new: null,
|
||||
|
||||
/**
|
||||
* Specifies if after an eval or switch operation, the variable or property
|
||||
* which has been edited should be disabled.
|
||||
*/
|
||||
preventDisableOnChage: false,
|
||||
preventDisableOnChange: false,
|
||||
|
||||
/**
|
||||
* Specifies if, whenever a variable or property descriptor is available,
|
||||
@ -825,6 +834,10 @@ VariablesView.prototype = {
|
||||
item._onDelete(e);
|
||||
}
|
||||
return;
|
||||
|
||||
case e.DOM_VK_INSERT:
|
||||
item._onAddProperty(e);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
@ -911,12 +924,22 @@ VariablesView.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets if action buttons (like delete) should be placed at the beginning or
|
||||
* end of a line.
|
||||
* @return boolean
|
||||
*/
|
||||
get actionsFirst() {
|
||||
return this._actionsFirst;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets if action buttons (like delete) should be placed at the beginning or
|
||||
* end of a line.
|
||||
* @param boolean aFlag
|
||||
*/
|
||||
set actionsFirst(aFlag) {
|
||||
this._actionsFirst = aFlag;
|
||||
if (aFlag) {
|
||||
this._parent.setAttribute("actions-first", "");
|
||||
} else {
|
||||
@ -956,6 +979,8 @@ VariablesView.prototype = {
|
||||
_currHierarchy: null,
|
||||
_enumVisible: true,
|
||||
_nonEnumVisible: true,
|
||||
_alignedValues: false,
|
||||
_actionsFirst: false,
|
||||
_parent: null,
|
||||
_list: null,
|
||||
_searchboxNode: null,
|
||||
@ -1152,7 +1177,8 @@ function Scope(aView, aName, aFlags = {}) {
|
||||
this.eval = aView.eval;
|
||||
this.switch = aView.switch;
|
||||
this.delete = aView.delete;
|
||||
this.preventDisableOnChage = aView.preventDisableOnChage;
|
||||
this.new = aView.new;
|
||||
this.preventDisableOnChange = aView.preventDisableOnChange;
|
||||
this.preventDescriptorModifiers = aView.preventDescriptorModifiers;
|
||||
this.editableNameTooltip = aView.editableNameTooltip;
|
||||
this.editableValueTooltip = aView.editableValueTooltip;
|
||||
@ -1259,6 +1285,20 @@ Scope.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove this Scope from its parent and remove all children recursively.
|
||||
*/
|
||||
remove: function() {
|
||||
let view = this._variablesView;
|
||||
view._store.splice(view._store.indexOf(this), 1);
|
||||
view._itemsByElement.delete(this._target);
|
||||
view._currHierarchy.delete(this._nameString);
|
||||
this._target.remove();
|
||||
for (let variable of this._store.values()) {
|
||||
variable.remove();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the variable in this container having the specified name.
|
||||
*
|
||||
@ -1683,7 +1723,6 @@ Scope.prototype = {
|
||||
*/
|
||||
_onClick: function(e) {
|
||||
if (e.button != 0 ||
|
||||
e.target == this._inputNode ||
|
||||
e.target == this._editNode ||
|
||||
e.target == this._deleteNode) {
|
||||
return;
|
||||
@ -2037,6 +2076,7 @@ Scope.prototype = {
|
||||
eval: null,
|
||||
switch: null,
|
||||
delete: null,
|
||||
new: null,
|
||||
editableValueTooltip: "",
|
||||
editableNameTooltip: "",
|
||||
editButtonTooltip: "",
|
||||
@ -2130,6 +2170,19 @@ Variable.prototype = Heritage.extend(Scope.prototype, {
|
||||
return new Property(this, aName, aDescriptor);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove this Variable from its parent and remove all children recursively.
|
||||
*/
|
||||
remove: function() {
|
||||
this.ownerView._store.delete(this._nameString);
|
||||
this._variablesView._itemsByElement.delete(this._target);
|
||||
this._variablesView._currHierarchy.delete(this._absoluteName);
|
||||
this._target.remove();
|
||||
for (let property of this._store.values()) {
|
||||
property.remove();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Populates this variable to contain all the properties of an object.
|
||||
*
|
||||
@ -2313,14 +2366,11 @@ Variable.prototype = Heritage.extend(Scope.prototype, {
|
||||
this._idString = generateId(this._nameString = aName);
|
||||
this._displayScope(aName, "variables-view-variable variable-or-property");
|
||||
|
||||
// Don't allow displaying variable information there's no name available.
|
||||
if (this._nameString) {
|
||||
this._displayVariable();
|
||||
this._customizeVariable();
|
||||
this._prepareTooltips();
|
||||
this._setAttributes();
|
||||
this._addEventListeners();
|
||||
}
|
||||
this._displayVariable();
|
||||
this._customizeVariable();
|
||||
this._prepareTooltips();
|
||||
this._setAttributes();
|
||||
this._addEventListeners();
|
||||
|
||||
this._onInit(this.ownerView._store.size < LAZY_APPEND_BATCH);
|
||||
},
|
||||
@ -2421,12 +2471,25 @@ Variable.prototype = Heritage.extend(Scope.prototype, {
|
||||
editNode.addEventListener("mousedown", this._onEdit.bind(this), false);
|
||||
this._title.insertBefore(editNode, this._spacer);
|
||||
}
|
||||
|
||||
if (ownerView.delete) {
|
||||
let deleteNode = this._deleteNode = this.document.createElement("toolbarbutton");
|
||||
deleteNode.className = "plain variables-view-delete";
|
||||
deleteNode.addEventListener("click", this._onDelete.bind(this), false);
|
||||
this._title.appendChild(deleteNode);
|
||||
}
|
||||
|
||||
let { actionsFirst } = this._variablesView;
|
||||
if (ownerView.new || actionsFirst) {
|
||||
let addPropertyNode = this._addPropertyNode = this.document.createElement("toolbarbutton");
|
||||
addPropertyNode.className = "plain variables-view-add-property";
|
||||
addPropertyNode.addEventListener("mousedown", this._onAddProperty.bind(this), false);
|
||||
if (actionsFirst && VariablesView.isPrimitive(descriptor)) {
|
||||
addPropertyNode.setAttribute("invisible", "");
|
||||
}
|
||||
this._title.appendChild(addPropertyNode);
|
||||
}
|
||||
|
||||
if (ownerView.contextMenuId) {
|
||||
this._title.setAttribute("context", ownerView.contextMenuId);
|
||||
}
|
||||
@ -2582,149 +2645,43 @@ Variable.prototype = Heritage.extend(Scope.prototype, {
|
||||
this._title.addEventListener("mousedown", this._onClick, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a textbox node in place of a label.
|
||||
*
|
||||
* @param nsIDOMNode aLabel
|
||||
* The label to be replaced with a textbox.
|
||||
* @param string aClassName
|
||||
* The class to be applied to the textbox.
|
||||
* @param object aCallbacks
|
||||
* An object containing the onKeypress and onBlur callbacks.
|
||||
*/
|
||||
_activateInput: function(aLabel, aClassName, aCallbacks) {
|
||||
let initialString = aLabel.getAttribute("value");
|
||||
|
||||
// Create a texbox input element which will be shown in the current
|
||||
// element's specified label location.
|
||||
let input = this.document.createElement("textbox");
|
||||
input.className = "plain " + aClassName;
|
||||
input.setAttribute("value", initialString);
|
||||
if (!this._variablesView.alignedValues) {
|
||||
input.setAttribute("flex", "1");
|
||||
}
|
||||
|
||||
// Replace the specified label with a textbox input element.
|
||||
aLabel.parentNode.replaceChild(input, aLabel);
|
||||
this._variablesView.boxObject.ensureElementIsVisible(input);
|
||||
input.select();
|
||||
|
||||
// When the value is a string (displayed as "value"), then we probably want
|
||||
// to change it to another string in the textbox, so to avoid typing the ""
|
||||
// again, tackle with the selection bounds just a bit.
|
||||
if (aLabel.getAttribute("value").match(/^".+"$/)) {
|
||||
input.selectionEnd--;
|
||||
input.selectionStart++;
|
||||
}
|
||||
|
||||
input.addEventListener("keypress", aCallbacks.onKeypress, false);
|
||||
input.addEventListener("blur", aCallbacks.onBlur, false);
|
||||
|
||||
this._prevExpandable = this.twisty;
|
||||
this._prevExpanded = this.expanded;
|
||||
this.collapse();
|
||||
this.hideArrow();
|
||||
this._locked = true;
|
||||
|
||||
this._inputNode = input;
|
||||
this._stopThrobber();
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the textbox node in place of a label.
|
||||
*
|
||||
* @param nsIDOMNode aLabel
|
||||
* The label which was replaced with a textbox.
|
||||
* @param object aCallbacks
|
||||
* An object containing the onKeypress and onBlur callbacks.
|
||||
*/
|
||||
_deactivateInput: function(aLabel, aInput, aCallbacks) {
|
||||
aInput.parentNode.replaceChild(aLabel, aInput);
|
||||
this._variablesView.boxObject.scrollBy(-this._target.clientWidth, 0);
|
||||
|
||||
aInput.removeEventListener("keypress", aCallbacks.onKeypress, false);
|
||||
aInput.removeEventListener("blur", aCallbacks.onBlur, false);
|
||||
|
||||
this._locked = false;
|
||||
this.twisty = this._prevExpandable;
|
||||
this.expanded = this._prevExpanded;
|
||||
|
||||
this._inputNode = null;
|
||||
this._stopThrobber();
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes this variable's name editable.
|
||||
*/
|
||||
_activateNameInput: function(e) {
|
||||
if (e && e.button != 0) {
|
||||
// Only allow left-click to trigger this event.
|
||||
return;
|
||||
}
|
||||
if (!this.ownerView.switch) {
|
||||
return;
|
||||
}
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (!this._variablesView.alignedValues) {
|
||||
this._separatorLabel.hidden = true;
|
||||
this._valueLabel.hidden = true;
|
||||
}
|
||||
|
||||
this._onNameInputKeyPress = this._onNameInputKeyPress.bind(this);
|
||||
this._deactivateNameInput = this._deactivateNameInput.bind(this);
|
||||
|
||||
this._activateInput(this._name, "element-name-input", {
|
||||
onKeypress: this._onNameInputKeyPress,
|
||||
onBlur: this._deactivateNameInput
|
||||
});
|
||||
this._separatorLabel.hidden = true;
|
||||
this._valueLabel.hidden = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Deactivates this variable's editable name mode.
|
||||
*/
|
||||
_deactivateNameInput: function(e) {
|
||||
this._deactivateInput(this._name, e.target, {
|
||||
onKeypress: this._onNameInputKeyPress,
|
||||
onBlur: this._deactivateNameInput
|
||||
});
|
||||
this._separatorLabel.hidden = false;
|
||||
this._valueLabel.hidden = false;
|
||||
EditableName.create(this, {
|
||||
onSave: aKey => {
|
||||
if (!this._variablesView.preventDisableOnChange) {
|
||||
this._disable();
|
||||
}
|
||||
this.ownerView.switch(this, aKey);
|
||||
},
|
||||
onCleanup: () => {
|
||||
if (!this._variablesView.alignedValues) {
|
||||
this._separatorLabel.hidden = false;
|
||||
this._valueLabel.hidden = false;
|
||||
}
|
||||
}
|
||||
}, e);
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes this variable's value editable.
|
||||
*/
|
||||
_activateValueInput: function(e) {
|
||||
if (e && e.button != 0) {
|
||||
// Only allow left-click to trigger this event.
|
||||
return;
|
||||
}
|
||||
if (!this.ownerView.eval) {
|
||||
return;
|
||||
}
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
this._onValueInputKeyPress = this._onValueInputKeyPress.bind(this);
|
||||
this._deactivateValueInput = this._deactivateValueInput.bind(this);
|
||||
|
||||
this._activateInput(this._valueLabel, "element-value-input", {
|
||||
onKeypress: this._onValueInputKeyPress,
|
||||
onBlur: this._deactivateValueInput
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Deactivates this variable's editable value mode.
|
||||
*/
|
||||
_deactivateValueInput: function(e) {
|
||||
this._deactivateInput(this._valueLabel, e.target, {
|
||||
onKeypress: this._onValueInputKeyPress,
|
||||
onBlur: this._deactivateValueInput
|
||||
});
|
||||
EditableValue.create(this, {
|
||||
onSave: aString => {
|
||||
if (!this._variablesView.preventDisableOnChange) {
|
||||
this._disable();
|
||||
}
|
||||
this.ownerView.eval(this.evaluationMacro(this, aString));
|
||||
}
|
||||
}, e);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2742,85 +2699,12 @@ Variable.prototype = Heritage.extend(Scope.prototype, {
|
||||
this._nonenum.hidden = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Deactivates this variable's editable mode and callbacks the new name.
|
||||
*/
|
||||
_saveNameInput: function(e) {
|
||||
let input = e.target;
|
||||
let initialString = this._name.getAttribute("value");
|
||||
let currentString = input.value.trim();
|
||||
this._deactivateNameInput(e);
|
||||
|
||||
if (initialString != currentString) {
|
||||
if (!this._variablesView.preventDisableOnChage) {
|
||||
this._disable();
|
||||
this._name.value = currentString;
|
||||
}
|
||||
this.ownerView.switch(this, currentString);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Deactivates this variable's editable mode and evaluates the new value.
|
||||
*/
|
||||
_saveValueInput: function(e) {
|
||||
let input = e.target;
|
||||
let initialString = this._valueLabel.getAttribute("value");
|
||||
let currentString = input.value.trim();
|
||||
this._deactivateValueInput(e);
|
||||
|
||||
if (initialString != currentString) {
|
||||
if (!this._variablesView.preventDisableOnChage) {
|
||||
this._disable();
|
||||
}
|
||||
this.ownerView.eval(this.evaluationMacro(this, currentString.trim()));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The current macro used to generate the string evaluated when performing
|
||||
* a variable or property value change.
|
||||
*/
|
||||
evaluationMacro: VariablesView.simpleValueEvalMacro,
|
||||
|
||||
/**
|
||||
* The key press listener for this variable's editable name textbox.
|
||||
*/
|
||||
_onNameInputKeyPress: function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
switch(e.keyCode) {
|
||||
case e.DOM_VK_RETURN:
|
||||
case e.DOM_VK_ENTER:
|
||||
this._saveNameInput(e);
|
||||
this.focus();
|
||||
return;
|
||||
case e.DOM_VK_ESCAPE:
|
||||
this._deactivateNameInput(e);
|
||||
this.focus();
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The key press listener for this variable's editable value textbox.
|
||||
*/
|
||||
_onValueInputKeyPress: function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
switch(e.keyCode) {
|
||||
case e.DOM_VK_RETURN:
|
||||
case e.DOM_VK_ENTER:
|
||||
this._saveValueInput(e);
|
||||
this.focus();
|
||||
return;
|
||||
case e.DOM_VK_ESCAPE:
|
||||
this._deactivateValueInput(e);
|
||||
this.focus();
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for the edit button.
|
||||
*/
|
||||
@ -2852,15 +2736,48 @@ Variable.prototype = Heritage.extend(Scope.prototype, {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for the add property button.
|
||||
*/
|
||||
_onAddProperty: function(e) {
|
||||
if ("button" in e && e.button != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
this.expanded = true;
|
||||
|
||||
let item = this.addItem(" ", {
|
||||
value: undefined,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true
|
||||
}, true);
|
||||
|
||||
// Force showing the separator.
|
||||
item._separatorLabel.hidden = false;
|
||||
|
||||
EditableNameAndValue.create(item, {
|
||||
onSave: ([aKey, aValue]) => {
|
||||
if (!this._variablesView.preventDisableOnChange) {
|
||||
this._disable();
|
||||
}
|
||||
this.ownerView.new(this, aKey, aValue);
|
||||
}
|
||||
}, e);
|
||||
},
|
||||
|
||||
_symbolicName: "",
|
||||
_absoluteName: "",
|
||||
_initialDescriptor: null,
|
||||
_separatorLabel: null,
|
||||
_spacer: null,
|
||||
_valueLabel: null,
|
||||
_inputNode: null,
|
||||
_editNode: null,
|
||||
_deleteNode: null,
|
||||
_addPropertyNode: null,
|
||||
_tooltip: null,
|
||||
_valueGrip: null,
|
||||
_valueString: "",
|
||||
@ -2895,18 +2812,15 @@ Property.prototype = Heritage.extend(Variable.prototype, {
|
||||
* @param object aDescriptor
|
||||
* The property's descriptor.
|
||||
*/
|
||||
_init: function(aName, aDescriptor) {
|
||||
_init: function(aName = "", aDescriptor) {
|
||||
this._idString = generateId(this._nameString = aName);
|
||||
this._displayScope(aName, "variables-view-property variable-or-property");
|
||||
|
||||
// Don't allow displaying property information there's no name available.
|
||||
if (this._nameString) {
|
||||
this._displayVariable();
|
||||
this._customizeVariable();
|
||||
this._prepareTooltips();
|
||||
this._setAttributes();
|
||||
this._addEventListeners();
|
||||
}
|
||||
this._displayVariable();
|
||||
this._customizeVariable();
|
||||
this._prepareTooltips();
|
||||
this._setAttributes();
|
||||
this._addEventListeners();
|
||||
|
||||
this._onInit(this.ownerView._store.size < LAZY_APPEND_BATCH);
|
||||
},
|
||||
@ -3263,3 +3177,262 @@ let generateId = (function() {
|
||||
return aName.toLowerCase().trim().replace(/\s+/g, "-") + (++count);
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
/**
|
||||
* An Editable encapsulates the UI of an edit box that overlays a label,
|
||||
* allowing the user to edit the value.
|
||||
*
|
||||
* @param Variable aVariable
|
||||
* The Variable or Property to make editable.
|
||||
* @param object aOptions
|
||||
* - onSave
|
||||
* The callback to call with the value when editing is complete.
|
||||
* - onCleanup
|
||||
* The callback to call when the editable is removed for any reason.
|
||||
*/
|
||||
function Editable(aVariable, aOptions) {
|
||||
this._variable = aVariable;
|
||||
this._onSave = aOptions.onSave;
|
||||
this._onCleanup = aOptions.onCleanup;
|
||||
}
|
||||
|
||||
Editable.create = function(aVariable, aOptions, aEvent) {
|
||||
let editable = new this(aVariable, aOptions);
|
||||
editable.activate(aEvent);
|
||||
return editable;
|
||||
};
|
||||
|
||||
Editable.prototype = {
|
||||
/**
|
||||
* The class name for targeting this Editable type's label element. Overridden
|
||||
* by inheriting classes.
|
||||
*/
|
||||
className: null,
|
||||
|
||||
/**
|
||||
* Boolean indicating whether this Editable should activate. Overridden by
|
||||
* inheriting classes.
|
||||
*/
|
||||
shouldActivate: null,
|
||||
|
||||
/**
|
||||
* The label element for this Editable. Overridden by inheriting classes.
|
||||
*/
|
||||
label: null,
|
||||
|
||||
/**
|
||||
* Activate this editable by replacing the input box it overlays and
|
||||
* initialize the handlers.
|
||||
*
|
||||
* @param Event e [optional]
|
||||
* Optionally, the Event object that was used to activate the Editable.
|
||||
*/
|
||||
activate: function(e) {
|
||||
if (!this.shouldActivate) {
|
||||
return;
|
||||
}
|
||||
|
||||
let { label } = this;
|
||||
let initialString = label.getAttribute("value");
|
||||
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
// Create a texbox input element which will be shown in the current
|
||||
// element's specified label location.
|
||||
let input = this._input = this._variable.document.createElement("textbox");
|
||||
input.className = "plain " + this.className;
|
||||
input.setAttribute("value", initialString);
|
||||
if (!this._variable._variablesView.alignedValues) {
|
||||
input.setAttribute("flex", "1");
|
||||
}
|
||||
|
||||
// Replace the specified label with a textbox input element.
|
||||
label.parentNode.replaceChild(input, label);
|
||||
this._variable._variablesView.boxObject.ensureElementIsVisible(input);
|
||||
input.select();
|
||||
|
||||
// When the value is a string (displayed as "value"), then we probably want
|
||||
// to change it to another string in the textbox, so to avoid typing the ""
|
||||
// again, tackle with the selection bounds just a bit.
|
||||
if (initialString.match(/^".+"$/)) {
|
||||
input.selectionEnd--;
|
||||
input.selectionStart++;
|
||||
}
|
||||
|
||||
this._onKeypress = this._onKeypress.bind(this);
|
||||
this._onBlur = this._onBlur.bind(this);
|
||||
input.addEventListener("keypress", this._onKeypress);
|
||||
input.addEventListener("blur", this._onBlur);
|
||||
|
||||
this._prevExpandable = this._variable.twisty;
|
||||
this._prevExpanded = this._variable.expanded;
|
||||
this._variable.collapse();
|
||||
this._variable.hideArrow();
|
||||
this._variable.locked = true;
|
||||
this._variable._stopThrobber();
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the input box and restore the Variable or Property to its previous
|
||||
* state.
|
||||
*/
|
||||
deactivate: function() {
|
||||
this._input.removeEventListener("keypress", this._onKeypress);
|
||||
this._input.removeEventListener("blur", this.deactivate);
|
||||
this._input.parentNode.replaceChild(this.label, this._input);
|
||||
this._input = null;
|
||||
|
||||
let { boxObject } = this._variable._variablesView;
|
||||
boxObject.scrollBy(-this._variable._target, 0);
|
||||
this._variable.locked = false;
|
||||
this._variable.twisty = this._prevExpandable;
|
||||
this._variable.expanded = this._prevExpanded;
|
||||
this._variable._stopThrobber();
|
||||
},
|
||||
|
||||
/**
|
||||
* Save the current value and deactivate the Editable.
|
||||
*/
|
||||
_save: function() {
|
||||
let initial = this.label.getAttribute("value");
|
||||
let current = this._input.value.trim();
|
||||
this.deactivate();
|
||||
if (initial != current) {
|
||||
this._onSave(current);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when tab is pressed, allowing subclasses to link different
|
||||
* behavior to tabbing if desired.
|
||||
*/
|
||||
_next: function() {
|
||||
this._save();
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when escape is pressed, indicating a cancelling of editing without
|
||||
* saving.
|
||||
*/
|
||||
_reset: function() {
|
||||
this.deactivate();
|
||||
this._variable.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for when the input loses focus.
|
||||
*/
|
||||
_onBlur: function() {
|
||||
this.deactivate();
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for when the input receives a key press.
|
||||
*/
|
||||
_onKeypress: function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
switch (e.keyCode) {
|
||||
case e.DOM_VK_TAB:
|
||||
this._next();
|
||||
break;
|
||||
case e.DOM_VK_RETURN:
|
||||
case e.DOM_VK_ENTER:
|
||||
this._save();
|
||||
break;
|
||||
case e.DOM_VK_ESCAPE:
|
||||
this._reset();
|
||||
break;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* An Editable specific to editing the name of a Variable or Property.
|
||||
*/
|
||||
function EditableName(aVariable, aOptions) {
|
||||
Editable.call(this, aVariable, aOptions);
|
||||
}
|
||||
|
||||
EditableName.create = Editable.create;
|
||||
|
||||
EditableName.prototype = Heritage.extend(Editable.prototype, {
|
||||
className: "element-name-input",
|
||||
|
||||
get label() {
|
||||
return this._variable._name;
|
||||
},
|
||||
|
||||
get shouldActivate() {
|
||||
return !!this._variable.ownerView.switch;
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* An Editable specific to editing the value of a Variable or Property.
|
||||
*/
|
||||
function EditableValue(aVariable, aOptions) {
|
||||
Editable.call(this, aVariable, aOptions);
|
||||
}
|
||||
|
||||
EditableValue.create = Editable.create;
|
||||
|
||||
EditableValue.prototype = Heritage.extend(Editable.prototype, {
|
||||
className: "element-value-input",
|
||||
|
||||
get label() {
|
||||
return this._variable._valueLabel;
|
||||
},
|
||||
|
||||
get shouldActivate() {
|
||||
return !!this._variable.ownerView.eval;
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* An Editable specific to editing the key and value of a new property.
|
||||
*/
|
||||
function EditableNameAndValue(aVariable, aOptions) {
|
||||
EditableName.call(this, aVariable, aOptions);
|
||||
}
|
||||
|
||||
EditableNameAndValue.create = Editable.create;
|
||||
|
||||
EditableNameAndValue.prototype = Heritage.extend(EditableName.prototype, {
|
||||
_reset: function(e) {
|
||||
// Hide the Varible or Property if the user presses escape.
|
||||
this._variable.remove();
|
||||
this.deactivate();
|
||||
},
|
||||
|
||||
_next: function(e) {
|
||||
// Override _next so as to set both key and value at the same time.
|
||||
let key = this._input.value;
|
||||
this.label.setAttribute("value", key);
|
||||
|
||||
let valueEditable = EditableValue.create(this._variable, {
|
||||
onSave: aValue => {
|
||||
this._onSave([key, aValue]);
|
||||
},
|
||||
onCleanup: () => {
|
||||
this._onCleanup();
|
||||
}
|
||||
});
|
||||
valueEditable._reset = () => {
|
||||
this._variable.remove();
|
||||
valueEditable.deactivate();
|
||||
};
|
||||
},
|
||||
|
||||
_save: function(e) {
|
||||
// Both _save and _next activate the value edit box.
|
||||
this._next(e);
|
||||
}
|
||||
});
|
||||
|
@ -63,10 +63,16 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
*:not(:hover) .variables-view-delete {
|
||||
*:not(:hover) .variables-view-delete,
|
||||
*:not(:hover) .variables-view-add-property {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.variables-view-delete > .toolbarbutton-text,
|
||||
.variables-view-add-property > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.variables-view-container[aligned-values] .title > [optional-visibility] {
|
||||
display: none;
|
||||
}
|
||||
|
@ -615,10 +615,15 @@
|
||||
|
||||
/* Actions first */
|
||||
|
||||
.variables-view-container[actions-first] .variables-view-delete {
|
||||
.variables-view-container[actions-first] .variables-view-delete,
|
||||
.variables-view-container[actions-first] .variables-view-add-property {
|
||||
-moz-box-ordinal-group: 0;
|
||||
}
|
||||
|
||||
.variables-view-container[actions-first] [invisible] {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* Variables and properties tooltips */
|
||||
|
||||
.variable-or-property > tooltip > label {
|
||||
@ -654,10 +659,6 @@
|
||||
-moz-image-region: rect(0,48px,16px,32px);
|
||||
}
|
||||
|
||||
.variables-view-delete > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.variables-view-edit {
|
||||
background: url("chrome://browser/skin/devtools/vview-edit.png") center no-repeat;
|
||||
width: 20px;
|
||||
|
@ -258,6 +258,7 @@ browser.jar:
|
||||
skin/classic/browser/devtools/app-manager/error.svg (../shared/devtools/app-manager/images/error.svg)
|
||||
skin/classic/browser/devtools/app-manager/plus.svg (../shared/devtools/app-manager/images/plus.svg)
|
||||
skin/classic/browser/devtools/app-manager/remove.svg (../shared/devtools/app-manager/images/remove.svg)
|
||||
skin/classic/browser/devtools/app-manager/add.svg (../shared/devtools/app-manager/images/add.svg)
|
||||
skin/classic/browser/devtools/app-manager/index-icons.svg (../shared/devtools/app-manager/images/index-icons.svg)
|
||||
skin/classic/browser/devtools/app-manager/rocket.svg (../shared/devtools/app-manager/images/rocket.svg)
|
||||
skin/classic/browser/devtools/app-manager/noise.png (../shared/devtools/app-manager/images/noise.png)
|
||||
|
@ -609,10 +609,15 @@
|
||||
|
||||
/* Actions first */
|
||||
|
||||
.variables-view-container[actions-first] .variables-view-delete {
|
||||
.variables-view-container[actions-first] .variables-view-delete,
|
||||
.variables-view-container[actions-first] .variables-view-add-property {
|
||||
-moz-box-ordinal-group: 0;
|
||||
}
|
||||
|
||||
.variables-view-container[actions-first] [invisible] {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* Variables and properties tooltips */
|
||||
|
||||
.variable-or-property > tooltip > label {
|
||||
@ -648,10 +653,6 @@
|
||||
-moz-image-region: rect(0,48px,16px,32px);
|
||||
}
|
||||
|
||||
.variables-view-delete > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.variables-view-edit {
|
||||
background: url("chrome://browser/skin/devtools/vview-edit.png") center no-repeat;
|
||||
width: 20px;
|
||||
|
@ -360,6 +360,7 @@ browser.jar:
|
||||
skin/classic/browser/devtools/app-manager/error.svg (../shared/devtools/app-manager/images/error.svg)
|
||||
skin/classic/browser/devtools/app-manager/plus.svg (../shared/devtools/app-manager/images/plus.svg)
|
||||
skin/classic/browser/devtools/app-manager/remove.svg (../shared/devtools/app-manager/images/remove.svg)
|
||||
skin/classic/browser/devtools/app-manager/add.svg (../shared/devtools/app-manager/images/add.svg)
|
||||
skin/classic/browser/devtools/app-manager/index-icons.svg (../shared/devtools/app-manager/images/index-icons.svg)
|
||||
skin/classic/browser/devtools/app-manager/rocket.svg (../shared/devtools/app-manager/images/rocket.svg)
|
||||
skin/classic/browser/devtools/app-manager/noise.png (../shared/devtools/app-manager/images/noise.png)
|
||||
|
13
browser/themes/shared/devtools/app-manager/images/add.svg
Normal file
13
browser/themes/shared/devtools/app-manager/images/add.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="64px" height="64px" viewBox="0 0 64 64">
|
||||
<path fill="#00B2F7" d="M32.336,3.894c-15.74,0-28.5,12.76-28.5,28.5s12.76,28.5,28.5,28.5s28.5-12.76,28.5-28.5
|
||||
S48.076,3.894,32.336,3.894z M44.86,36.966h-7.823v7.62c0,2.582-2.12,4.702-4.702,4.702c-2.584,0-4.704-2.12-4.704-4.702v-7.62
|
||||
h-7.817c-2.52,0-4.572-2.056-4.572-4.572s2.053-4.572,4.572-4.572h7.817v-7.62c0-2.582,2.12-4.702,4.704-4.702
|
||||
c2.582,0,4.702,2.12,4.702,4.702v7.62h7.823c2.514,0,4.57,2.056,4.57,4.572S47.374,36.966,44.86,36.966z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 934 B |
@ -6,7 +6,7 @@
|
||||
|
||||
.variables-view-container.manifest-editor {
|
||||
background-color: #F5F5F5;
|
||||
padding: 20px 13px;
|
||||
padding: 20px 2px;
|
||||
}
|
||||
|
||||
.manifest-editor .variable-or-property:focus > .title {
|
||||
@ -19,7 +19,8 @@
|
||||
color: #27406A;
|
||||
}
|
||||
|
||||
.manifest-editor .variable-or-property > .title > label {
|
||||
.manifest-editor .variable-or-property > .title > label,
|
||||
.manifest-editor textbox {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
@ -52,16 +53,28 @@
|
||||
|
||||
.manifest-editor .variables-view-delete,
|
||||
.manifest-editor .variables-view-delete:hover,
|
||||
.manifest-editor .variables-view-delete:active {
|
||||
.manifest-editor .variables-view-delete:active,
|
||||
.manifest-editor .variables-view-add-property,
|
||||
.manifest-editor .variables-view-add-property:hover,
|
||||
.manifest-editor .variables-view-add-property:active {
|
||||
list-style-image: none;
|
||||
-moz-image-region: initial;
|
||||
}
|
||||
|
||||
.manifest-editor .variables-view-delete::before {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
.manifest-editor .variables-view-delete::before,
|
||||
.manifest-editor .variables-view-add-property::before {
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
background-image: url("app-manager/remove.svg");
|
||||
background-size: 12px auto;
|
||||
background-size: 11px auto;
|
||||
}
|
||||
|
||||
.manifest-editor .variables-view-delete::before {
|
||||
background-image: url("app-manager/remove.svg");
|
||||
}
|
||||
|
||||
.manifest-editor .variables-view-add-property::before {
|
||||
background-image: url("app-manager/add.svg");
|
||||
-moz-margin-end: 2px;
|
||||
}
|
||||
|
@ -612,10 +612,15 @@
|
||||
|
||||
/* Actions first */
|
||||
|
||||
.variables-view-container[actions-first] .variables-view-delete {
|
||||
.variables-view-container[actions-first] .variables-view-delete,
|
||||
.variables-view-container[actions-first] .variables-view-add-property {
|
||||
-moz-box-ordinal-group: 0;
|
||||
}
|
||||
|
||||
.variables-view-container[actions-first] [invisible] {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* Variables and properties tooltips */
|
||||
|
||||
.variable-or-property > tooltip > label {
|
||||
@ -651,10 +656,6 @@
|
||||
-moz-image-region: rect(0,48px,16px,32px);
|
||||
}
|
||||
|
||||
.variables-view-delete > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.variables-view-edit {
|
||||
background: url("chrome://browser/skin/devtools/vview-edit.png") center no-repeat;
|
||||
width: 20px;
|
||||
|
@ -282,6 +282,7 @@ browser.jar:
|
||||
skin/classic/browser/devtools/app-manager/error.svg (../shared/devtools/app-manager/images/error.svg)
|
||||
skin/classic/browser/devtools/app-manager/plus.svg (../shared/devtools/app-manager/images/plus.svg)
|
||||
skin/classic/browser/devtools/app-manager/remove.svg (../shared/devtools/app-manager/images/remove.svg)
|
||||
skin/classic/browser/devtools/app-manager/add.svg (../shared/devtools/app-manager/images/add.svg)
|
||||
skin/classic/browser/devtools/app-manager/index-icons.svg (../shared/devtools/app-manager/images/index-icons.svg)
|
||||
skin/classic/browser/devtools/app-manager/rocket.svg (../shared/devtools/app-manager/images/rocket.svg)
|
||||
skin/classic/browser/devtools/app-manager/noise.png (../shared/devtools/app-manager/images/noise.png)
|
||||
@ -583,6 +584,7 @@ browser.jar:
|
||||
skin/classic/aero/browser/devtools/app-manager/error.svg (../shared/devtools/app-manager/images/error.svg)
|
||||
skin/classic/aero/browser/devtools/app-manager/plus.svg (../shared/devtools/app-manager/images/plus.svg)
|
||||
skin/classic/aero/browser/devtools/app-manager/remove.svg (../shared/devtools/app-manager/images/remove.svg)
|
||||
skin/classic/aero/browser/devtools/app-manager/add.svg (../shared/devtools/app-manager/images/add.svg)
|
||||
skin/classic/aero/browser/devtools/app-manager/index-icons.svg (../shared/devtools/app-manager/images/index-icons.svg)
|
||||
skin/classic/aero/browser/devtools/app-manager/rocket.svg (../shared/devtools/app-manager/images/rocket.svg)
|
||||
skin/classic/aero/browser/devtools/app-manager/noise.png (../shared/devtools/app-manager/images/noise.png)
|
||||
|
Loading…
Reference in New Issue
Block a user