Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
b39a0869
Commit
b39a0869
authored
Mar 29, 2017
by
Robert Knight
Committed by
GitHub
Mar 29, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #317 from hypothesis/hypothesis-app-component
Convert `<hypothesis-app>` to a component
parents
b3df274a
4f213ab3
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
147 additions
and
154 deletions
+147
-154
app.js
src/sidebar/app.js
+6
-8
hypothesis-app.js
src/sidebar/components/hypothesis-app.js
+39
-32
hypothesis-app-test.js
src/sidebar/components/test/hypothesis-app-test.js
+60
-60
app.js
src/sidebar/directive/app.js
+0
-12
app.html
src/sidebar/templates/app.html
+0
-42
hypothesis_app.html
src/sidebar/templates/hypothesis_app.html
+42
-0
No files found.
src/sidebar/app.js
View file @
b39a0869
...
...
@@ -60,24 +60,22 @@ function configureLocation($locationProvider) {
// @ngInject
function
configureRoutes
(
$routeProvider
)
{
// The `vm.{auth,search}` properties used in these templates come from the
// `<hypothesis-app>` component which hosts the router's container element.
$routeProvider
.
when
(
'/a/:id'
,
{
template
:
'<annotation-viewer-content search="search"></annotation-viewer-content>'
,
template
:
'<annotation-viewer-content search="
vm.
search"></annotation-viewer-content>'
,
reloadOnSearch
:
false
,
resolve
:
resolve
,
});
$routeProvider
.
when
(
'/stream'
,
{
template
:
'<stream-content search="search"></stream-content>'
,
template
:
'<stream-content search="
vm.
search"></stream-content>'
,
reloadOnSearch
:
false
,
resolve
:
resolve
,
});
$routeProvider
.
otherwise
({
// Trivial template for use until the other controllers are also converted
// to components and we can remove the router entirely.
//
// The "search" and "auth" properties are provided by "AppController".
template
:
'<sidebar-content search="search" auth="auth"></sidebar-content>'
,
template
:
'<sidebar-content search="vm.search" auth="vm.auth"></sidebar-content>'
,
reloadOnSearch
:
false
,
resolve
:
resolve
,
});
...
...
@@ -128,7 +126,7 @@ module.exports = angular.module('h', [
])
// The root component for the application
.
directive
(
'hypothesisApp'
,
require
(
'./directive/
app'
))
.
component
(
'hypothesisApp'
,
require
(
'./components/hypothesis-
app'
))
// UI components
.
component
(
'annotation'
,
require
(
'./components/annotation'
).
component
)
...
...
src/sidebar/
app-controller
.js
→
src/sidebar/
components/hypothesis-app
.js
View file @
b39a0869
...
...
@@ -2,11 +2,11 @@
var
scrollIntoView
=
require
(
'scroll-into-view'
);
var
events
=
require
(
'./events'
);
var
parseAccountID
=
require
(
'./filter/persona'
).
parseAccountID
;
var
scopeTimeout
=
require
(
'./util/scope-timeout'
);
var
serviceConfig
=
require
(
'./service-config'
);
var
bridgeEvents
=
require
(
'../shared/bridge-events'
);
var
events
=
require
(
'.
.
/events'
);
var
parseAccountID
=
require
(
'.
.
/filter/persona'
).
parseAccountID
;
var
scopeTimeout
=
require
(
'.
.
/util/scope-timeout'
);
var
serviceConfig
=
require
(
'.
.
/service-config'
);
var
bridgeEvents
=
require
(
'../
../
shared/bridge-events'
);
function
authStateFromUserID
(
userid
)
{
if
(
userid
)
{
...
...
@@ -23,54 +23,55 @@ function authStateFromUserID(userid) {
}
// @ngInject
module
.
exports
=
function
AppController
(
function
Hypothesis
AppController
(
$document
,
$location
,
$rootScope
,
$route
,
$scope
,
$window
,
analytics
,
annotationUI
,
auth
,
bridge
,
drafts
,
features
,
frameSync
,
groups
,
serviceUrl
,
session
,
settings
,
streamer
)
{
var
self
=
this
;
// This stores information about the current user's authentication status.
// When the controller instantiates we do not yet know if the user is
// logged-in or not, so it has an initial status of 'unknown'. This can be
// used by templates to show an intermediate or loading state.
$scope
.
auth
=
{
status
:
'unknown'
};
this
.
auth
=
{
status
:
'unknown'
};
// Allow all child scopes to look up feature flags as:
//
// if ($scope.feature('foo')) { ... }
$scope
.
feature
=
features
.
flagEnabled
;
this
.
feature
=
features
.
flagEnabled
;
// Allow all child scopes access to the session
$scope
.
session
=
session
;
this
.
session
=
session
;
// App dialogs
$scope
.
accountDialog
=
{
visible
:
false
};
$scope
.
shareDialog
=
{
visible
:
false
};
$scope
.
helpPanel
=
{
visible
:
false
};
this
.
accountDialog
=
{
visible
:
false
};
this
.
shareDialog
=
{
visible
:
false
};
this
.
helpPanel
=
{
visible
:
false
};
// Check to see if we're in the sidebar, or on a standalone page such as
// the stream page or an individual annotation page.
$scope
.
isSidebar
=
$window
.
top
!==
$window
;
if
(
$scope
.
isSidebar
)
{
this
.
isSidebar
=
$window
.
top
!==
$window
;
if
(
this
.
isSidebar
)
{
frameSync
.
connect
();
}
$scope
.
serviceUrl
=
serviceUrl
;
this
.
serviceUrl
=
serviceUrl
;
$scope
.
sortKey
=
function
()
{
this
.
sortKey
=
function
()
{
return
annotationUI
.
getState
().
sortKey
;
};
$scope
.
sortKeysAvailable
=
function
()
{
this
.
sortKeysAvailable
=
function
()
{
return
annotationUI
.
getState
().
sortKeysAvailable
;
};
$scope
.
setSortKey
=
annotationUI
.
setSortKey
;
this
.
setSortKey
=
annotationUI
.
setSortKey
;
// Reload the view when the user switches accounts
$scope
.
$on
(
events
.
USER_CHANGED
,
function
(
event
,
data
)
{
$scope
.
auth
=
authStateFromUserID
(
data
.
userid
);
$scope
.
accountDialog
.
visible
=
false
;
self
.
auth
=
authStateFromUserID
(
data
.
userid
);
self
.
accountDialog
.
visible
=
false
;
if
(
!
data
||
!
data
.
initialLoad
)
{
$route
.
reload
();
...
...
@@ -81,10 +82,10 @@ module.exports = function AppController(
// When the authentication status of the user is known,
// update the auth info in the top bar and show the login form
// after first install of the extension.
$scope
.
auth
=
authStateFromUserID
(
state
.
userid
);
self
.
auth
=
authStateFromUserID
(
state
.
userid
);
if
(
!
state
.
userid
&&
settings
.
openLoginForm
)
{
$scope
.
login
();
self
.
login
();
}
});
...
...
@@ -98,23 +99,23 @@ module.exports = function AppController(
}
// Start the login flow. This will present the user with the login dialog.
$scope
.
login
=
function
()
{
this
.
login
=
function
()
{
if
(
serviceConfig
(
settings
))
{
bridge
.
call
(
bridgeEvents
.
DO_LOGIN
);
return
;
}
$scope
.
accountDialog
.
visible
=
true
;
self
.
accountDialog
.
visible
=
true
;
scrollToView
(
'login-form'
);
};
$scope
.
signUp
=
function
(){
this
.
signUp
=
function
(){
analytics
.
track
(
analytics
.
events
.
SIGN_UP_REQUESTED
);
};
// Display the dialog for sharing the current page
$scope
.
share
=
function
()
{
$scope
.
shareDialog
.
visible
=
true
;
this
.
share
=
function
()
{
this
.
shareDialog
.
visible
=
true
;
scrollToView
(
'share-dialog'
);
};
...
...
@@ -133,7 +134,7 @@ module.exports = function AppController(
};
// Log the user out.
$scope
.
logout
=
function
()
{
this
.
logout
=
function
()
{
if
(
!
promptToLogout
())
{
return
;
}
...
...
@@ -141,11 +142,11 @@ module.exports = function AppController(
$rootScope
.
$emit
(
events
.
ANNOTATION_DELETED
,
draft
);
});
drafts
.
discard
();
$scope
.
accountDialog
.
visible
=
false
;
this
.
accountDialog
.
visible
=
false
;
session
.
logout
();
};
$scope
.
search
=
{
this
.
search
=
{
query
:
function
()
{
return
annotationUI
.
getState
().
filterQuery
;
},
...
...
@@ -154,6 +155,12 @@ module.exports = function AppController(
},
};
$scope
.
countPendingUpdates
=
streamer
.
countPendingUpdates
;
$scope
.
applyPendingUpdates
=
streamer
.
applyPendingUpdates
;
this
.
countPendingUpdates
=
streamer
.
countPendingUpdates
;
this
.
applyPendingUpdates
=
streamer
.
applyPendingUpdates
;
}
module
.
exports
=
{
controller
:
HypothesisAppController
,
controllerAs
:
'vm'
,
template
:
require
(
'../templates/hypothesis_app.html'
),
};
src/sidebar/
test/app-controller
-test.js
→
src/sidebar/
components/test/hypothesis-app
-test.js
View file @
b39a0869
...
...
@@ -3,12 +3,12 @@
var
angular
=
require
(
'angular'
);
var
proxyquire
=
require
(
'proxyquire'
);
var
events
=
require
(
'../events'
);
var
bridgeEvents
=
require
(
'../../shared/bridge-events'
);
var
util
=
require
(
'../../shared/test/util'
);
var
events
=
require
(
'../
../
events'
);
var
bridgeEvents
=
require
(
'../../
../
shared/bridge-events'
);
var
util
=
require
(
'../../
../
shared/test/util'
);
describe
(
'
AppController
'
,
function
()
{
var
$controller
=
null
;
describe
(
'
hypothesisApp
'
,
function
()
{
var
$co
mponentCo
ntroller
=
null
;
var
$scope
=
null
;
var
$rootScope
=
null
;
var
fakeAnnotationMetadata
=
null
;
...
...
@@ -35,7 +35,7 @@ describe('AppController', function () {
var
createController
=
function
(
locals
)
{
locals
=
locals
||
{};
locals
.
$scope
=
$scope
;
return
$co
ntroller
(
'AppController
'
,
locals
);
return
$co
mponentController
(
'hypothesisApp
'
,
locals
);
};
beforeEach
(
function
()
{
...
...
@@ -49,14 +49,14 @@ describe('AppController', function () {
fakeServiceConfig
=
sandbox
.
stub
();
var
AppController
=
proxyquire
(
'../app-controller
'
,
util
.
noCallThru
({
var
component
=
proxyquire
(
'../hypothesis-app
'
,
util
.
noCallThru
({
'angular'
:
angular
,
'./annotation-metadata'
:
fakeAnnotationMetadata
,
'./service-config'
:
fakeServiceConfig
,
'.
.
/annotation-metadata'
:
fakeAnnotationMetadata
,
'.
.
/service-config'
:
fakeServiceConfig
,
}));
angular
.
module
(
'h'
,
[])
.
co
ntroller
(
'AppController'
,
AppController
);
.
co
mponent
(
'hypothesisApp'
,
component
);
});
beforeEach
(
angular
.
mock
.
module
(
'h'
));
...
...
@@ -69,7 +69,7 @@ describe('AppController', function () {
fakeAnalytics
=
{
track
:
sandbox
.
stub
(),
events
:
require
(
'../analytics'
)().
events
,
events
:
require
(
'../
../
analytics'
)().
events
,
};
fakeAuth
=
{};
...
...
@@ -140,8 +140,8 @@ describe('AppController', function () {
$provide
.
value
(
'$window'
,
fakeWindow
);
}));
beforeEach
(
angular
.
mock
.
inject
(
function
(
_$controller_
,
_$rootScope_
)
{
$co
ntroller
=
_$c
ontroller_
;
beforeEach
(
angular
.
mock
.
inject
(
function
(
_$co
mponentCo
ntroller_
,
_$rootScope_
)
{
$co
mponentController
=
_$componentC
ontroller_
;
$rootScope
=
_$rootScope_
;
$scope
=
$rootScope
.
$new
();
}));
...
...
@@ -154,14 +154,14 @@ describe('AppController', function () {
it
(
'is false if the window is the top window'
,
function
()
{
fakeWindow
.
top
=
fakeWindow
;
createController
();
assert
.
isFalse
(
$scope
.
isSidebar
);
var
ctrl
=
createController
();
assert
.
isFalse
(
ctrl
.
isSidebar
);
});
it
(
'is true if the window is not the top window'
,
function
()
{
fakeWindow
.
top
=
{};
createController
();
assert
.
isTrue
(
$scope
.
isSidebar
);
var
ctrl
=
createController
();
assert
.
isTrue
(
ctrl
.
isSidebar
);
});
});
...
...
@@ -178,14 +178,14 @@ describe('AppController', function () {
});
it
(
'auth.status is "unknown" on startup'
,
function
()
{
createController
();
assert
.
equal
(
$scope
.
auth
.
status
,
'unknown'
);
var
ctrl
=
createController
();
assert
.
equal
(
ctrl
.
auth
.
status
,
'unknown'
);
});
it
(
'sets auth.status to "logged-out" if userid is null'
,
function
()
{
createController
();
var
ctrl
=
createController
();
return
fakeSession
.
load
().
then
(
function
()
{
assert
.
equal
(
$scope
.
auth
.
status
,
'logged-out'
);
assert
.
equal
(
ctrl
.
auth
.
status
,
'logged-out'
);
});
});
...
...
@@ -193,9 +193,9 @@ describe('AppController', function () {
fakeSession
.
load
=
function
()
{
return
Promise
.
resolve
({
userid
:
'acct:jim@hypothes.is'
});
};
createController
();
var
ctrl
=
createController
();
return
fakeSession
.
load
().
then
(
function
()
{
assert
.
equal
(
$scope
.
auth
.
status
,
'logged-in'
);
assert
.
equal
(
ctrl
.
auth
.
status
,
'logged-in'
);
});
});
...
...
@@ -203,22 +203,22 @@ describe('AppController', function () {
fakeSession
.
load
=
function
()
{
return
Promise
.
resolve
({
userid
:
'acct:jim@hypothes.is'
});
};
createController
();
var
ctrl
=
createController
();
return
fakeSession
.
load
().
then
(
function
()
{
assert
.
equal
(
$scope
.
auth
.
userid
,
'acct:jim@hypothes.is'
);
assert
.
equal
(
$scope
.
auth
.
username
,
'jim'
);
assert
.
equal
(
$scope
.
auth
.
provider
,
'hypothes.is'
);
assert
.
equal
(
ctrl
.
auth
.
userid
,
'acct:jim@hypothes.is'
);
assert
.
equal
(
ctrl
.
auth
.
username
,
'jim'
);
assert
.
equal
(
ctrl
.
auth
.
provider
,
'hypothes.is'
);
});
});
it
(
'updates auth when the logged-in user changes'
,
function
()
{
createController
();
var
ctrl
=
createController
();
return
fakeSession
.
load
().
then
(
function
()
{
$scope
.
$broadcast
(
events
.
USER_CHANGED
,
{
initialLoad
:
false
,
userid
:
'acct:john@hypothes.is'
,
});
assert
.
deepEqual
(
$scope
.
auth
,
{
assert
.
deepEqual
(
ctrl
.
auth
,
{
status
:
'logged-in'
,
userid
:
'acct:john@hypothes.is'
,
username
:
'john'
,
...
...
@@ -227,19 +227,19 @@ describe('AppController', function () {
});
});
it
(
'exposes the serviceUrl on the
scope
'
,
function
()
{
createController
();
assert
.
equal
(
$scope
.
serviceUrl
,
fakeServiceUrl
);
it
(
'exposes the serviceUrl on the
controller
'
,
function
()
{
var
ctrl
=
createController
();
assert
.
equal
(
ctrl
.
serviceUrl
,
fakeServiceUrl
);
});
it
(
'does not show login form for logged in users'
,
function
()
{
createController
();
assert
.
isFalse
(
$scope
.
accountDialog
.
visible
);
var
ctrl
=
createController
();
assert
.
isFalse
(
ctrl
.
accountDialog
.
visible
);
});
it
(
'does not show the share dialog at start'
,
function
()
{
createController
();
assert
.
isFalse
(
$scope
.
shareDialog
.
visible
);
var
ctrl
=
createController
();
assert
.
isFalse
(
ctrl
.
shareDialog
.
visible
);
});
it
(
'does not reload the view when the logged-in user changes on first load'
,
function
()
{
...
...
@@ -257,8 +257,8 @@ describe('AppController', function () {
});
it
(
'tracks sign up requests in analytics'
,
function
()
{
createController
();
$scope
.
signUp
();
var
ctrl
=
createController
();
ctrl
.
signUp
();
assert
.
calledWith
(
fakeAnalytics
.
track
,
fakeAnalytics
.
events
.
SIGN_UP_REQUESTED
);
});
...
...
@@ -266,9 +266,9 @@ describe('AppController', function () {
it
(
'shows the login dialog if not using a third-party service'
,
function
()
{
// If no third-party annotation service is in use then it should show the
// built-in login dialog.
createController
();
$scope
.
login
();
assert
.
equal
(
$scope
.
accountDialog
.
visible
,
true
);
var
ctrl
=
createController
();
ctrl
.
login
();
assert
.
equal
(
ctrl
.
accountDialog
.
visible
,
true
);
});
it
(
'sends DO_LOGIN if a third-party service is in use'
,
function
()
{
...
...
@@ -277,9 +277,9 @@ describe('AppController', function () {
// (so that the partner site we're embedded in can do its own login
// thing).
fakeServiceConfig
.
returns
({});
createController
();
var
ctrl
=
createController
();
$scope
.
login
();
ctrl
.
login
();
assert
.
equal
(
fakeBridge
.
call
.
callCount
,
1
);
assert
.
isTrue
(
fakeBridge
.
call
.
calledWithExactly
(
bridgeEvents
.
DO_LOGIN
));
...
...
@@ -288,24 +288,24 @@ describe('AppController', function () {
describe
(
'#share()'
,
function
()
{
it
(
'shows the share dialog'
,
function
()
{
createController
();
$scope
.
share
();
assert
.
equal
(
$scope
.
shareDialog
.
visible
,
true
);
var
ctrl
=
createController
();
ctrl
.
share
();
assert
.
equal
(
ctrl
.
shareDialog
.
visible
,
true
);
});
});
describe
(
'#logout()'
,
function
()
{
it
(
'calls session.logout()'
,
function
()
{
createController
();
$scope
.
logout
();
var
ctrl
=
createController
();
ctrl
.
logout
();
assert
.
called
(
fakeSession
.
logout
);
});
it
(
'prompts the user if there are drafts'
,
function
()
{
fakeDrafts
.
count
.
returns
(
1
);
createController
();
var
ctrl
=
createController
();
$scope
.
logout
();
ctrl
.
logout
();
assert
.
equal
(
fakeWindow
.
confirm
.
callCount
,
1
);
});
...
...
@@ -314,10 +314,10 @@ describe('AppController', function () {
fakeDrafts
.
unsaved
=
sandbox
.
stub
().
returns
(
[
'draftOne'
,
'draftTwo'
,
'draftThree'
]
);
createController
();
var
ctrl
=
createController
();
$rootScope
.
$emit
=
sandbox
.
stub
();
$scope
.
logout
();
ctrl
.
logout
();
assert
(
$rootScope
.
$emit
.
calledThrice
);
assert
.
deepEqual
(
...
...
@@ -329,39 +329,39 @@ describe('AppController', function () {
});
it
(
'discards draft annotations'
,
function
()
{
createController
();
var
ctrl
=
createController
();
$scope
.
logout
();
ctrl
.
logout
();
assert
(
fakeDrafts
.
discard
.
calledOnce
);
});
it
(
'does not emit "annotationDeleted" if the user cancels the prompt'
,
function
()
{
createController
();
var
ctrl
=
createController
();
fakeDrafts
.
count
.
returns
(
1
);
$rootScope
.
$emit
=
sandbox
.
stub
();
fakeWindow
.
confirm
.
returns
(
false
);
$scope
.
logout
();
ctrl
.
logout
();
assert
(
$rootScope
.
$emit
.
notCalled
);
});
it
(
'does not discard drafts if the user cancels the prompt'
,
function
()
{
createController
();
var
ctrl
=
createController
();
fakeDrafts
.
count
.
returns
(
1
);
fakeWindow
.
confirm
.
returns
(
false
);
$scope
.
logout
();
ctrl
.
logout
();
assert
(
fakeDrafts
.
discard
.
notCalled
);
});
it
(
'does not prompt if there are no drafts'
,
function
()
{
createController
();
var
ctrl
=
createController
();
fakeDrafts
.
count
.
returns
(
0
);
$scope
.
logout
();
ctrl
.
logout
();
assert
.
equal
(
fakeWindow
.
confirm
.
callCount
,
0
);
});
...
...
src/sidebar/directive/app.js
deleted
100644 → 0
View file @
b3df274a
'use strict'
;
var
AppController
=
require
(
'../app-controller'
);
module
.
exports
=
function
()
{
return
{
restrict
:
'E'
,
controller
:
AppController
,
scope
:
{},
template
:
require
(
'../templates/app.html'
),
};
};
src/sidebar/templates/app.html
deleted
100644 → 0
View file @
b3df274a
<div
class=
"app-content-wrapper"
h-branding=
"appBackgroundColor"
>
<top-bar
auth=
"auth"
on-login=
"login()"
on-sign-up=
"signUp()"
on-logout=
"logout()"
on-share-page=
"share()"
on-show-help-panel=
"helpPanel.visible = true"
is-sidebar=
"::isSidebar"
pending-update-count=
"countPendingUpdates()"
on-apply-pending-updates=
"applyPendingUpdates()"
search-controller=
"search"
sort-key=
"sortKey()"
sort-keys-available=
"sortKeysAvailable()"
on-change-sort-key=
"setSortKey(sortKey)"
>
</top-bar>
<div
class=
"create-account-banner"
ng-if=
"isSidebar && auth.status === 'logged-out'"
ng-cloak
>
To annotate this document
<a
href=
"{{ serviceUrl('signup') }}"
target=
"_blank"
>
create a free account
</a>
or
<a
href=
""
ng-click=
"login()"
>
log in
</a>
</div>
<div
class=
"content"
ng-cloak
>
<login-form
ng-if=
"accountDialog.visible"
on-close=
"accountDialog.visible = false"
>
</login-form>
<sidebar-tutorial
ng-if=
"isSidebar"
></sidebar-tutorial>
<share-dialog
ng-if=
"shareDialog.visible"
on-close=
"shareDialog.visible = false"
>
</share-dialog>
<help-panel
ng-if=
"helpPanel.visible"
on-close=
"helpPanel.visible = false"
auth=
"auth"
>
</help-panel>
<main
ng-view=
""
></main>
</div>
</div>
src/sidebar/templates/hypothesis_app.html
0 → 100644
View file @
b39a0869
<div
class=
"app-content-wrapper"
h-branding=
"appBackgroundColor"
>
<top-bar
auth=
"vm.auth"
on-login=
"vm.login()"
on-sign-up=
"vm.signUp()"
on-logout=
"vm.logout()"
on-share-page=
"vm.share()"
on-show-help-panel=
"vm.helpPanel.visible = true"
is-sidebar=
"::vm.isSidebar"
pending-update-count=
"vm.countPendingUpdates()"
on-apply-pending-updates=
"vm.applyPendingUpdates()"
search-controller=
"vm.search"
sort-key=
"vm.sortKey()"
sort-keys-available=
"vm.sortKeysAvailable()"
on-change-sort-key=
"vm.setSortKey(sortKey)"
>
</top-bar>
<div
class=
"create-account-banner"
ng-if=
"vm.isSidebar && vm.auth.status === 'logged-out'"
ng-cloak
>
To annotate this document
<a
href=
"{{ vm.serviceUrl('signup') }}"
target=
"_blank"
>
create a free account
</a>
or
<a
href=
""
ng-click=
"vm.login()"
>
log in
</a>
</div>
<div
class=
"content"
ng-cloak
>
<login-form
ng-if=
"vm.accountDialog.visible"
on-close=
"vm.accountDialog.visible = false"
>
</login-form>
<sidebar-tutorial
ng-if=
"vm.isSidebar"
></sidebar-tutorial>
<share-dialog
ng-if=
"vm.shareDialog.visible"
on-close=
"vm.shareDialog.visible = false"
>
</share-dialog>
<help-panel
ng-if=
"vm.helpPanel.visible"
on-close=
"vm.helpPanel.visible = false"
auth=
"vm.auth"
>
</help-panel>
<main
ng-view=
""
></main>
</div>
</div>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment