Bug 687698 - Integrate Style Editor's automatic transitions; r=rcampbell,dao

This commit is contained in:
Cedric Vivier 2012-01-13 00:26:39 +08:00
parent b42ef163e5
commit e924270603
3 changed files with 81 additions and 6 deletions

View File

@ -1041,6 +1041,7 @@ pref("devtools.scratchpad.enabled", true);
// Enable the Style Editor.
pref("devtools.styleeditor.enabled", true);
pref("devtools.styleeditor.transitions", true);
// Enable tools for Chrome development.
pref("devtools.chrome.enabled", false);

View File

@ -59,6 +59,23 @@ const UPDATE_STYLESHEET_THROTTLE_DELAY = 500;
// @see StyleEditor._persistExpando
const STYLESHEET_EXPANDO = "-moz-styleeditor-stylesheet-";
const TRANSITIONS_PREF = "devtools.styleeditor.transitions";
const TRANSITION_CLASS = "moz-styleeditor-transitioning";
const TRANSITION_DURATION_MS = 500;
const TRANSITION_RULE = "\
:root.moz-styleeditor-transitioning, :root.moz-styleeditor-transitioning * {\
-moz-transition-duration: " + TRANSITION_DURATION_MS + "ms !important; \
-moz-transition-delay: 0ms !important;\
-moz-transition-timing-function: ease-out !important;\
-moz-transition-property: all !important;\
}";
/**
* Style Editor module-global preferences
*/
const TRANSITIONS_ENABLED = Services.prefs.getBoolPref(TRANSITIONS_PREF);
/**
* StyleEditor constructor.
@ -107,6 +124,9 @@ function StyleEditor(aDocument, aStyleSheet)
// this is to perform pending updates before editor closing
this._onWindowUnloadBinding = this._onWindowUnload.bind(this);
this._transitionRefCount = 0;
this._focusOnSourceEditorReady = false;
}
@ -405,8 +425,13 @@ StyleEditor.prototype = {
* Arguments: (StyleEditor editor)
* @see inputElement
*
* onCommit: Called when changes have been committed/applied
* to the live DOM style sheet.
* onUpdate: Called when changes are being applied to the live
* DOM style sheet but might not be complete from
* a WYSIWYG perspective (eg. transitioned update).
* Arguments: (StyleEditor editor)
*
* onCommit: Called when changes have been completely committed
* /applied to the live DOM style sheet.
* Arguments: (StyleEditor editor)
* }
*
@ -640,15 +665,50 @@ StyleEditor.prototype = {
let source = this._state.text;
let oldNode = this.styleSheet.ownerNode;
let oldIndex = this.styleSheetIndex;
let newNode = this.contentDocument.createElement("style");
let content = this.contentDocument;
let newNode = content.createElement("style");
newNode.setAttribute("type", "text/css");
newNode.appendChild(this.contentDocument.createTextNode(source));
newNode.appendChild(content.createTextNode(source));
oldNode.parentNode.replaceChild(newNode, oldNode);
this._styleSheet = this.contentDocument.styleSheets[oldIndex];
this._styleSheet = content.styleSheets[oldIndex];
this._persistExpando();
if (!TRANSITIONS_ENABLED) {
this._triggerAction("Update");
this._triggerAction("Commit");
return;
}
// Insert the global transition rule
// Use a ref count to make sure we do not add it multiple times.. and remove
// it only when all pending StyleEditor-generated transitions ended.
if (!this._transitionRefCount) {
this._styleSheet.insertRule(TRANSITION_RULE, 0);
content.documentElement.classList.add(TRANSITION_CLASS);
}
this._transitionRefCount++;
// Set up clean up and commit after transition duration (+10% buffer)
// @see _onTransitionEnd
content.defaultView.setTimeout(this._onTransitionEnd.bind(this),
Math.floor(TRANSITION_DURATION_MS * 1.1));
this._triggerAction("Update");
},
/**
* This cleans up class and rule added for transition effect and then trigger
* Commit as the changes have been completed.
*/
_onTransitionEnd: function SE__onTransitionEnd()
{
if (--this._transitionRefCount == 0) {
this.contentDocument.documentElement.classList.remove(TRANSITION_CLASS);
this.styleSheet.deleteRule(0);
}
this._triggerAction("Commit");
},

View File

@ -4,6 +4,8 @@
const TESTCASE_URI = TEST_BASE + "simple.html";
const TRANSITION_CLASS = "moz-styleeditor-transitioning";
function test()
{
@ -30,6 +32,7 @@ function run(aChrome)
let gAddedCount = 0; // to add new stylesheet after the 2 initial stylesheets
let gNewEditor; // to make sure only one new stylesheet got created
let gUpdateCount = 0; // to make sure only one Update event is triggered
let gCommitCount = 0; // to make sure only one Commit event is triggered
function testEditorAdded(aChrome, aEditor)
@ -82,6 +85,13 @@ function testEditorAdded(aChrome, aEditor)
}, gChromeWindow) ;
},
onUpdate: function (aEditor) {
gUpdateCount++;
ok(content.document.documentElement.classList.contains(TRANSITION_CLASS),
"StyleEditor's transition class has been added to content");
},
onCommit: function (aEditor) {
gCommitCount++;
@ -99,7 +109,11 @@ function testEditorAdded(aChrome, aEditor)
is(computedStyle.backgroundColor, "rgb(255, 0, 0)",
"content's background color has been updated to red");
ok(!content.document.documentElement.classList.contains(TRANSITION_CLASS),
"StyleEditor's transition class has been removed from content");
executeSoon(function () {
is(gUpdateCount, 1, "received only one Update event (throttle)");
is(gCommitCount, 1, "received only one Commit event (throttle)");
aEditor.removeActionListener(listener);