Skip to content

Commit 11b4cbc

Browse files
author
Hugo Rodrigues
committed
Big html/css refactor, new features
1 parent 926b7d9 commit 11b4cbc

File tree

5 files changed

+352
-169
lines changed

5 files changed

+352
-169
lines changed

Readme.md

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
# HH UI - Editor
2-
Angular Code Colaboration Editor with tab support.
1+
# hhEditor - HackHands Code Editor
2+
Angular directive for Code Colaboration Editor with tab support.
33

44
## Features
5-
- Tab system support
6-
- Multiuser (unlimited)
5+
- Multiple Editors support (using tab layout)
6+
- Standalone or multi-user Colaboration (using Firebase)
77
- Bidirectional syntax change
8+
- Bidirectional tab create
9+
- Bidirectional tab close
10+
- Bidirectional tab reorder
11+
- Bidirectional tab rename
12+
- Local files download (for every open tab)
813

914
## Config
1015

src/hhEditor.html

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
<div class="hhEditor">
2-
<div class="tabs" >
3-
<div id="sortable-container">
4-
<div class="sortable-row" as-sortable="sortableOptions" ng-model="tabs">
5-
<div class="onetab" ng-repeat="(key, item) in tabs" as-sortable-item>
6-
<div ng-click="focus(key)" class="tabButton" ng-class="{active: tabStatus.focus == key}" as-sortable-item-handle><div class="close" ng-click="close($event, key)">x</div><div class="title">{{item.title}}{{item.syntax.ext}}</div></div>
7-
</div>
8-
</div>
2+
<div class="tabs">
3+
<div id="sortable-container" class="rowTabs" as-sortable="sortableOptions" ng-model="tabs">
4+
<div ng-repeat="(key, item) in tabs" ng-click="clicked($event, key)" ng-class="{tabActive: tabStatus.focus == key}" as-sortable-item class="tab">
5+
<div ng-show="editing != key" as-sortable-item-handle class="tabTitle">{{item.title | titleDefault}}{{item.syntax.ext}}</div>
6+
<input show-focus="editing == key" ng-show="editing == key" ng-blur="hide(key)" ng-enter="hide(key)" ng-model="tabsData[item['$id']].title" class="tabTitleRename" />
7+
<strong ng-click="close($event, key)" class="tabClose">x</strong>
8+
</div>
9+
<div class="tab addNew" ng-click="add()">+</div>
910
</div>
10-
<div class="addNew" ng-click="add()">+</div>
1111
</div>
1212
<div class="tabsContents">
1313
<div ng-repeat="(key, item) in tabs" class="tabContent" ng-class="{active: tabStatus.focus == key}">
1414
<div class="editor">
1515
<div hh-firepad tabeditor="item" settings="settings" class="aceEditor"></div>
1616
</div>
17-
1817
<div class="editorStatus">
19-
<div class="cursor">Line {{item.row || "1"}}, Column {{item.column || "1"}}</div>
20-
<div class="syntax">Syntax: <select ng-model="item.syntax" ng-change="syntax(key)" ng-options="mode.name for mode in modes track by mode.name"></select></div>
18+
<div class="editorStatusContent"><a href="" class="download" ng-click="downloadAll()">&#8582;</a>
19+
<div class="cursor">Line {{item.row || "1"}}, Column {{item.column || "1"}} </div>
20+
<div class="syntax">Syntax: <select ng-model="item.syntax" ng-change="syntax(key)" ng-options="mode.name for mode in modes track by mode.name"></select></div>
21+
</div>
2122
</div>
2223
</div>
2324
</div>

src/hhEditor.js

+71-6
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,45 @@ angular.module('hhUI', ['ui.sortable', 'firebase'])
6464
return result;
6565
}
6666

67+
$scope.editing = null;
68+
6769
// Get default mode for new tabs
6870
settings.syntaxMode = getSyntax(settings.syntax);
6971
settings.initialSyntaxMode = getSyntax(settings.initialSyntax);
7072

73+
$scope.hide = function(key){
74+
$scope.editing = null;
75+
$scope.focus(key)
76+
}
77+
78+
$scope.clicked = function(event, key){
79+
if (event.which == 2)
80+
return $scope.close(event, key);
81+
82+
if (key == $scope.tabStatus.focus)
83+
$scope.editing = key;
84+
else
85+
$scope.focus(key)
86+
}
87+
88+
$scope.downloadAll = function () {
89+
angular.forEach($scope.tabs, function(value, key) {
90+
var title = (value.title || "Untitled")+''+value.syntax.ext
91+
var content = window.aces[value.id].getSession().getValue();
92+
$scope.download(title, content)
93+
});
94+
}
95+
96+
97+
$scope.download = function (filename, text) {
98+
var pom = document.createElement('a');
99+
pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
100+
pom.setAttribute('download', filename);
101+
document.body.appendChild(pom)
102+
pom.click();
103+
document.body.removeChild(pom)
104+
}
105+
71106

72107
$scope.syntax = function(key, syntax){
73108
var currentItem = $scope.tabs[key];
@@ -120,19 +155,19 @@ angular.module('hhUI', ['ui.sortable', 'firebase'])
120155
});
121156
}
122157

123-
124-
125158
// Initialize firebase connection
126159
var ref = new Firebase($scope.settings.firebase)
127160
$scope.tabStatus = $firebase(ref.child('status')).$asObject();
128161
$scope.tabs = $firebase(ref.child('tabs')).$asArray();
129162

163+
//var xxx = $firebase(ref.child('tabs')).$asObject();
164+
$firebase(ref.child('tabs')).$asObject().$bindTo($scope, "tabsData");
165+
130166
$scope.tabs.$loaded(function(){
131167
if ($scope.tabs.length == 0)
132168
$scope.add(settings.initialSyntaxMode, settings.initialText);
133169
});
134170

135-
136171
$scope.sortableOptions = {
137172
containment: '#sortable-container',
138173
//restrict move across columns. move only within column.
@@ -152,13 +187,12 @@ angular.module('hhUI', ['ui.sortable', 'firebase'])
152187

153188
$scope.focus(diff.dest.index)
154189
}
155-
};
190+
}
156191

157192
}]
158193
}
159194
}])
160195

161-
162196
.directive('hhFirepad', [function() {
163197

164198
return {
@@ -207,4 +241,35 @@ angular.module('hhUI', ['ui.sortable', 'firebase'])
207241
}
208242
}
209243

210-
}])
244+
}])
245+
246+
.directive('showFocus', function($timeout) {
247+
return function(scope, element, attrs) {
248+
scope.$watch(attrs.showFocus,
249+
function (newValue) {
250+
$timeout(function() {
251+
newValue && element[0].focus();
252+
});
253+
},true);
254+
};
255+
})
256+
257+
.directive('ngEnter', function () {
258+
return function (scope, element, attrs) {
259+
element.bind("keydown keypress", function (event) {
260+
if(event.which === 13) {
261+
scope.$apply(function (){
262+
scope.$eval(attrs.ngEnter);
263+
});
264+
265+
event.preventDefault();
266+
}
267+
});
268+
};
269+
})
270+
271+
.filter('titleDefault', function() {
272+
return function(input) {
273+
return input ? input : 'Untitled';
274+
};
275+
})

0 commit comments

Comments
 (0)