Bug 1139569 - Optimize update function for element editors in markup view;r=mratcliffe

Previously, any call to update() would destroy and recreate all attribute
editors.  This got really slow and caused a lot of unnecessary work, since
this ran any time any attribute changed.  Also, old attributes wouldn't
end up getting removed but would simply be hidden.  With this patch, we
update each attribute if it's changed, and any unused attributes are removed.
This commit is contained in:
Brian Grinstead 2015-03-09 10:02:21 -07:00
parent 5eda8219ac
commit a21890ea44
2 changed files with 25 additions and 23 deletions

View File

@ -2414,29 +2414,34 @@ ElementEditor.prototype = {
* Update the state of the editor from the node.
*/
update: function() {
let attrs = this.node.attributes;
if (!attrs) {
return;
}
let attrs = this.node.attributes || [];
let attrsToRemove = new Set(this.attrList.querySelectorAll(".attreditor"));
// Hide all the attribute editors, they'll be re-shown if they're
// still applicable. Don't update attributes that are being
// actively edited.
let attrEditors = this.attrList.querySelectorAll(".attreditor");
for (let i = 0; i < attrEditors.length; i++) {
if (!attrEditors[i].inplaceEditor) {
attrEditors[i].style.display = "none";
}
}
// Get the attribute editor for each attribute that exists on
// the node and show it.
// Only loop through the current attributes on the node, anything that's
// been removed will be removed from this DOM because it will be part of
// the attrsToRemove set.
for (let attr of attrs) {
let attribute = this._createAttribute(attr);
if (!attribute.inplaceEditor) {
let el = this.attrs[attr.name];
let valueChanged = el && el.querySelector(".attr-value").innerHTML !== attr.value;
let isEditing = el && el.querySelector(".editable").inplaceEditor;
let needToCreateAttributeEditor = el && (!valueChanged || isEditing);
if (needToCreateAttributeEditor) {
// Element already exists and doesn't need to be recreated.
// Just show it (it's hidden by default due to the template).
attrsToRemove.delete(el);
el.style.removeProperty("display");
} else {
// Create a new editor, because the value of an existing attribute
// has changed.
let attribute = this._createAttribute(attr);
attribute.style.removeProperty("display");
}
}
for (let el of attrsToRemove) {
el.remove();
}
},
_startModifyingAttributes: function() {

View File

@ -33,12 +33,9 @@ const TEST_DATA = [
node1.removeAttribute("newattr");
},
check: function*(inspector) {
// The markup-view is a little weird in that it doesn't remove the
// attribute but only hides it with display:none
let {editor} = yield getContainerForSelector("#node1", inspector);
ok([...editor.attrList.querySelectorAll(".attreditor")].some(attr => {
return attr.textContent.trim() === "newattr=\"newattrval\"" &&
attr.style.display === "none";
ok(![...editor.attrList.querySelectorAll(".attreditor")].some(attr => {
return attr.textContent.trim() === "newattr=\"newattrval\"";
}), "newattr attribute removed");
}
},