タブバーの位置変更履歴を自前で保持せず、ライブラリに任せるようにした

git-svn-id: http://www.cozmixng.org/repos/piro/treestyletab/trunk@5674 599a83e7-65a4-db11-8015-0010dcdd6dc2
This commit is contained in:
piro 2009-12-26 20:02:30 +00:00
parent c5e4858203
commit 6a4511f03f
4 changed files with 275 additions and 73 deletions

View File

@ -0,0 +1,267 @@
/*
UI Operations Global Undo History Manager
Usage:
// window specific events
window['piro.sakura.ne.jp'].operationHistory.addEntry(
'MyAddonFeature',
{ undo : function() { ... },
redo : function() { ... } },
window
);
window['piro.sakura.ne.jp'].operationHistory.undo('MyAddonFeature', window);
window['piro.sakura.ne.jp'].operationHistory.redo('MyAddonFeature', window);
// global events (not associated to window)
window['piro.sakura.ne.jp'].operationHistory.addEntry(
'MyAddonFeature',
{ ... }
);
window['piro.sakura.ne.jp'].operationHistory.undo('MyAddonFeature');
// anonymous, window specifit
window['piro.sakura.ne.jp'].operationHistory.addEntry({ ... }, window);
window['piro.sakura.ne.jp'].operationHistory.undo(window);
// anonymous, global
window['piro.sakura.ne.jp'].operationHistory.addEntry({ ... });
window['piro.sakura.ne.jp'].operationHistory.undo();
lisence: The MIT License, Copyright (c) 2009 SHIMODA "Piro" Hiroshi
http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/license.txt
original:
http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/operationHistory.js
*/
(function() {
const currentRevision = 1;
if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};
var loadedRevision = 'operationHistory' in window['piro.sakura.ne.jp'] ?
window['piro.sakura.ne.jp'].operationHistory.revision :
0 ;
if (loadedRevision && loadedRevision > currentRevision) {
return;
}
var tables = {};
if (loadedRevision) {
tables = window['piro.sakura.ne.jp'].operationHistory._tables;
window['piro.sakura.ne.jp'].destroy();
}
var Cc = Components.classes;
var Ci = Components.interfaces;
window['piro.sakura.ne.jp'].operationHistory = {
revision : currentRevision,
kMAX_ENTRIES : 999,
kWINDOW_ID : 'UIOperationGlobalHistoryWindowID',
_doingUndo : false,
_tables : tables,
initialized : false,
init : function()
{
var targets = this.WindowMediator.getZOrderDOMWindowEnumerator('navigator:browser', true);
while (targets.hasMoreElements())
{
let target = targets.getNext().QueryInterface(Ci.nsIDOMWindowInternal);
if (
'piro.sakura.ne.jp' in target &&
'operationHistory' in target['piro.sakura.ne.jp'] &&
target['piro.sakura.ne.jp'].operationHistory.initialized
) {
this._tables = target['piro.sakura.ne.jp'].operationHistory._tables;
break;
}
}
window.addEventListener('unload', this, false);
this.initialized = true;
},
destroy : function()
{
window.removeEventListener('unload', this, false);
},
addEntry : function()
{
if (this._doingUndo)
return;
var options = this._getOptionsFromArguments(arguments);
var history = options.history;
var entries = history.entries;
entries = entries.slice(0, history.index+1);
entries.push(options.data);
entries = entries.slice(-this.kMAX_ENTRIES);
history.entries = entries;
history.index = entries.length-1;
},
undo : function()
{
var options = this._getOptionsFromArguments(arguments);
var history = options.history;
if (history.index < 0)
return false;
var error;
this._doingUndo = true;
var data = history.entries[history.index--];
try {
data.undo();
}
catch(e) {
error = e;
}
this._dispatchEvent(options);
this._doingUndo = false;
if (error) throw error;
return true;
},
redo : function()
{
var options = this._getOptionsFromArguments(arguments);
var history = options.history;
if (history.index > history.entries.length-1)
return false;
var error;
this._doingUndo = true;
var data = history.entries[history.index++];
try {
data.redo();
}
catch(e) {
error = e;
}
this._dispatchEvent(options);
this._doingUndo = false;
if (error) throw error;
return true;
},
_dispatchEvent : function(aOptions)
{
var d = aOptions.window ? aOptions.window.document : document ;
var event = d.createEvent('Events');
event.initEvent('UIOperationGlobalHistoryUndo', true, false);
event.name = aOptions.name;
d.dispatchEvent(event);
},
_getOptionsFromArguments : function(aArguments)
{
var w, name, data;
Array.slice(aArguments).some(function(aArg) {
if (aArg instanceof Ci.nsIDOMWindow)
w = aArg;
else if (typeof aArg == 'string')
name = aArg;
else if (aArg)
data = aArg;
return (w && name && data);
});
if (!name)
name = w ? 'window' : 'global' ;
var windowId = this.SessionStore.getWindowValue(window, this.kWINDOW_ID);
if (!windowId) {
windowId = 'window-'+Date.now()+parseInt(Math.random() * 65000);
this.SessionStore.setWindowValue(window, this.kWINDOW_ID, windowId);
}
var tableName = w ? encodeURIComponent(name)+'::'+windowId : encodeURIComponent(name) ;
if (!(tableName in this._tables)) {
this._tables[tableName] = {
entries : [],
index : -1,
windowId : windowId
};
}
return {
name : name,
window : w,
windowId : windowId,
data : data,
history : this._tables[tableName]
};
},
_getWindowById : function(aId)
{
var targets = this.WindowMediator.getZOrderDOMWindowEnumerator('navigator:browser', true);
while (targets.hasMoreElements())
{
let target = targets.getNext().QueryInterface(Ci.nsIDOMWindowInternal);
if (aId == this.SessionStore.getWindowValue(target, this.kWINDOW_ID))
return target;
}
return null;
},
_deleteWindowTables : function()
{
var id = this.SessionStore.getWindowValue(window, this.kWINDOW_ID);
if (!id) return;
var removedTables = [];
for (let i in this._tables)
{
if (id == this._tables[i].windowId)
removedTables.push(i);
}
removedTables.forEach(function(aName) {
delete this._tables[aName];
}, this);
},
get WindowMediator() {
if (!this._WindowMediator) {
this._WindowMediator = Cc['@mozilla.org/appshell/window-mediator;1'].getService(Ci.nsIWindowMediator);
}
return this._WindowMediator;
},
_WindowMediator : null,
get SessionStore() {
if (!this._SessionStore) {
this._SessionStore = Cc['@mozilla.org/browser/sessionstore;1'].getService(Ci.nsISessionStore);
}
return this._SessionStore;
},
_SessionStore : null,
handleEvent : function(aEvent)
{
switch (aEvent.type)
{
case 'unload':
this._deleteWindowTables();
this.destroy();
return;
}
}
};
window['piro.sakura.ne.jp'].operationHistory.init();
})();

View File

@ -12,6 +12,7 @@
<script src="res/stopRendering.js" type="application/x-javascript; version=1.7"/>
<script src="res/extensions.js" type="application/x-javascript; version=1.7"/>
<script src="res/UninstallationListener.js" type="application/x-javascript; version=1.7"/>
<script src="res/operationHistory.js" type="application/x-javascript; version=1.7"/>
<script src="treestyletab.js" type="application/x-javascript; version=1.7"/>
<script src="treestyletabbrowser.js" type="application/x-javascript; version=1.7"/>

View File

@ -34,7 +34,14 @@ TreeStyleTabBrowserTabpanelDNDObserver.prototype = {
let orient = (position == 'left' || position == 'right') ? 'vertical' : 'horizontal' ;
sv.setTreePref('tabbar.fixed.'+orient, false);
}
var current = sv.currentTabbarPosition;
sv.currentTabbarPosition = position;
window['piro.sakura.ne.jp'].operationHistory.addEntry(
'TabbarDNDOperations',
{ undo : function() { sv.currentTabbarPosition = current; },
redo : function() { sv.currentTabbarPosition = position; } },
window
);
}
aEvent.stopPropagation();

View File

@ -242,8 +242,6 @@ var TreeStyleTabUtils = {
this.addPrefListener(this);
this.ObserverService.addObserver(this, 'private-browsing-change-granted', false);
this.onChangeTabbarPosition(this.currentTabbarPosition);
this.onPrefChange('extensions.treestyletab.indent');
this.onPrefChange('extensions.treestyletab.clickOnIndentSpaces.enabled');
this.onPrefChange('browser.link.open_newwindow.restriction.override');
@ -1444,73 +1442,6 @@ var TreeStyleTabUtils = {
return aValue;
},
undoChangeTabbarPosition : function TSTUtils_undoChangeTabbarPosition() /* PUBLIC API */
{
if (this._tabbarPositionHistoryIndex <= 0)
return false;
this._inRollbackTabbarPosition = true;
var current = this.currentTabbarPosition;
var previous;
do {
previous = this._tabbarPositionHistory[--this._tabbarPositionHistoryIndex];
}
while (previous && current == previous);
this.currentTabbarPosition = previous;
this._inRollbackTabbarPosition = false;
return current != previous;
},
redoChangeTabbarPosition : function TSTUtils_redoChangeTabbarPosition() /* PUBLIC API */
{
if (this._tabbarPositionHistoryIndex >= this._tabbarPositionHistory.length-1)
return false;
this._inRollbackTabbarPosition = true;
var current = this.currentTabbarPosition;
var next;
do {
next = this._tabbarPositionHistory[++this._tabbarPositionHistoryIndex];
}
while (next && current == next);
this.currentTabbarPosition = next;
this._inRollbackTabbarPosition = false;
return current != next;
},
onChangeTabbarPosition : function TSTUtils_onChangeTabbarPosition(aPosition)
{
var history = this._tabbarPositionHistory;
var current = history[this._tabbarPositionHistoryIndex];
if (
this._inRollbackTabbarPosition ||
(current && current == aPosition)
)
return;
history = history.slice(0, this._tabbarPositionHistoryIndex+1);
history.push(aPosition);
history = history.slice(-this.kMAX_TABBAR_POSITION_HISTORY);
this._tabbarPositionHistory = history;
this._tabbarPositionHistoryIndex = history.length-1;
},
_tabbarPositionHistory : [],
_tabbarPositionHistoryIndex : -1,
kMAX_TABBAR_POSITION_HISTORY : 999,
/* Pref Listener */
@ -1575,10 +1506,6 @@ var TreeStyleTabUtils = {
this.collapseDuration = value;
break;
case 'extensions.treestyletab.tabbar.position':
this.onChangeTabbarPosition(value);
break;
case 'extensions.treestyletab.twisty.expandSensitiveArea':
this.shouldExpandTwistyArea = value;
break;