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
8e1dfb7a
Commit
8e1dfb7a
authored
Apr 12, 2017
by
Sean Hammond
Committed by
GitHub
Apr 12, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #350 from hypothesis/extract-annotation-header
Extract annotation header into a separate component
parents
563d5a5f
e2228104
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
225 additions
and
112 deletions
+225
-112
app.js
src/sidebar/app.js
+1
-0
annotation-header.js
src/sidebar/components/annotation-header.js
+82
-0
annotation.js
src/sidebar/components/annotation.js
+5
-23
annotation-header-test.js
src/sidebar/components/test/annotation-header-test.js
+76
-0
annotation-test.js
src/sidebar/components/test/annotation-test.js
+3
-40
annotation-header.html
src/sidebar/templates/annotation-header.html
+49
-0
annotation.html
src/sidebar/templates/annotation.html
+9
-49
No files found.
src/sidebar/app.js
View file @
8e1dfb7a
...
@@ -130,6 +130,7 @@ module.exports = angular.module('h', [
...
@@ -130,6 +130,7 @@ module.exports = angular.module('h', [
// UI components
// UI components
.
component
(
'annotation'
,
require
(
'./components/annotation'
))
.
component
(
'annotation'
,
require
(
'./components/annotation'
))
.
component
(
'annotationHeader'
,
require
(
'./components/annotation-header'
))
.
component
(
'annotationShareDialog'
,
require
(
'./components/annotation-share-dialog'
))
.
component
(
'annotationShareDialog'
,
require
(
'./components/annotation-share-dialog'
))
.
component
(
'annotationThread'
,
require
(
'./components/annotation-thread'
))
.
component
(
'annotationThread'
,
require
(
'./components/annotation-thread'
))
.
component
(
'annotationViewerContent'
,
require
(
'./components/annotation-viewer-content'
))
.
component
(
'annotationViewerContent'
,
require
(
'./components/annotation-viewer-content'
))
...
...
src/sidebar/components/annotation-header.js
0 → 100644
View file @
8e1dfb7a
'use strict'
;
var
annotationMetadata
=
require
(
'../annotation-metadata'
);
var
memoize
=
require
(
'../util/memoize'
);
var
persona
=
require
(
'../filter/persona'
);
// @ngInject
function
AnnotationHeaderController
(
groups
,
settings
,
serviceUrl
)
{
var
self
=
this
;
this
.
user
=
function
()
{
return
self
.
annotation
.
user
;
};
this
.
username
=
function
()
{
return
persona
.
username
(
self
.
annotation
.
user
);
};
this
.
isThirdPartyUser
=
function
()
{
return
persona
.
isThirdPartyUser
(
self
.
annotation
.
user
,
settings
.
authDomain
);
};
this
.
serviceUrl
=
serviceUrl
;
this
.
group
=
function
()
{
return
groups
.
get
(
self
.
annotation
.
group
);
};
var
documentMeta
=
memoize
(
annotationMetadata
.
domainAndTitle
);
this
.
documentMeta
=
function
()
{
return
documentMeta
(
self
.
annotation
);
};
this
.
updated
=
function
()
{
return
self
.
annotation
.
updated
;
};
this
.
htmlLink
=
function
()
{
if
(
self
.
annotation
.
links
&&
self
.
annotation
.
links
.
html
)
{
return
self
.
annotation
.
links
.
html
;
}
return
''
;
};
}
/**
* Header component for an annotation card.
*
* Header which displays the username, last update timestamp and other key
* metadata about an annotation.
*/
module
.
exports
=
{
controller
:
AnnotationHeaderController
,
controllerAs
:
'vm'
,
bindings
:
{
/**
* The saved annotation
*/
annotation
:
'<'
,
/**
* True if the annotation is private or will become private when the user
* saves their changes.
*/
isPrivate
:
'<'
,
/** True if the user is currently editing the annotation. */
isEditing
:
'<'
,
/**
* True if the annotation is a highlight.
* FIXME: This should determined in AnnotationHeaderController
*/
isHighlight
:
'<'
,
onReplyCountClick
:
'&'
,
replyCount
:
'<'
,
/** True if document metadata should be shown. */
showDocumentInfo
:
'<'
,
},
template
:
require
(
'../templates/annotation-header.html'
),
};
src/sidebar/components/annotation.js
View file @
8e1dfb7a
...
@@ -4,7 +4,6 @@
...
@@ -4,7 +4,6 @@
var
annotationMetadata
=
require
(
'../annotation-metadata'
);
var
annotationMetadata
=
require
(
'../annotation-metadata'
);
var
events
=
require
(
'../events'
);
var
events
=
require
(
'../events'
);
var
memoize
=
require
(
'../util/memoize'
);
var
persona
=
require
(
'../filter/persona'
);
var
persona
=
require
(
'../filter/persona'
);
var
isNew
=
annotationMetadata
.
isNew
;
var
isNew
=
annotationMetadata
.
isNew
;
...
@@ -90,8 +89,6 @@ function AnnotationController(
...
@@ -90,8 +89,6 @@ function AnnotationController(
// The remaining properties on vm are read-only properties for the
// The remaining properties on vm are read-only properties for the
// templates.
// templates.
vm
.
serviceUrl
=
serviceUrl
;
/** Determines whether controls to expand/collapse the annotation body
/** Determines whether controls to expand/collapse the annotation body
* are displayed adjacent to the tags field.
* are displayed adjacent to the tags field.
*/
*/
...
@@ -458,10 +455,6 @@ function AnnotationController(
...
@@ -458,10 +455,6 @@ function AnnotationController(
return
vm
.
annotation
.
$orphan
;
return
vm
.
annotation
.
$orphan
;
};
};
vm
.
updated
=
function
()
{
return
vm
.
annotation
.
updated
;
};
vm
.
user
=
function
()
{
vm
.
user
=
function
()
{
return
vm
.
annotation
.
user
;
return
vm
.
annotation
.
user
;
};
};
...
@@ -470,10 +463,6 @@ function AnnotationController(
...
@@ -470,10 +463,6 @@ function AnnotationController(
return
persona
.
isThirdPartyUser
(
vm
.
annotation
.
user
,
settings
.
authDomain
);
return
persona
.
isThirdPartyUser
(
vm
.
annotation
.
user
,
settings
.
authDomain
);
};
};
vm
.
username
=
function
()
{
return
persona
.
username
(
vm
.
annotation
.
user
);
};
vm
.
isDeleted
=
function
()
{
vm
.
isDeleted
=
function
()
{
return
streamer
.
hasPendingDeletion
(
vm
.
annotation
.
id
);
return
streamer
.
hasPendingDeletion
(
vm
.
annotation
.
id
);
};
};
...
@@ -497,15 +486,13 @@ function AnnotationController(
...
@@ -497,15 +486,13 @@ function AnnotationController(
return
isReply
(
vm
.
annotation
);
return
isReply
(
vm
.
annotation
);
};
};
vm
.
links
=
function
()
{
vm
.
incontextLink
=
function
()
{
if
(
vm
.
annotation
.
links
)
{
if
(
vm
.
annotation
.
links
)
{
return
{
incontext
:
vm
.
annotation
.
links
.
incontext
||
return
vm
.
annotation
.
links
.
incontext
||
vm
.
annotation
.
links
.
html
||
vm
.
annotation
.
links
.
html
||
''
,
''
;
html
:
vm
.
annotation
.
links
.
html
};
}
else
{
return
{
incontext
:
''
,
html
:
''
};
}
}
return
''
;
};
};
/**
/**
...
@@ -552,11 +539,6 @@ function AnnotationController(
...
@@ -552,11 +539,6 @@ function AnnotationController(
};
};
};
};
var
documentMeta
=
memoize
(
annotationMetadata
.
domainAndTitle
);
vm
.
documentMeta
=
function
()
{
return
documentMeta
(
vm
.
annotation
);
};
init
();
init
();
}
}
...
...
src/sidebar/components/test/annotation-header-test.js
0 → 100644
View file @
8e1dfb7a
'use strict'
;
var
angular
=
require
(
'angular'
);
var
proxyquire
=
require
(
'proxyquire'
);
var
fixtures
=
require
(
'../../test/annotation-fixtures'
);
var
fakeDocumentMeta
=
{
domain
:
'docs.io'
,
titleLink
:
'http://docs.io/doc.html'
,
titleText
:
'Dummy title'
,
};
describe
(
'annotationHeader'
,
function
()
{
var
$componentController
;
var
fakeGroups
;
var
fakeSettings
;
var
fakeServiceUrl
;
before
(
function
()
{
var
annotationHeader
=
proxyquire
(
'../annotation-header'
,
{
'../annotation-metadata'
:
{
domainAndTitle
:
function
(
ann
)
{
// eslint-disable-line no-unused-vars
return
fakeDocumentMeta
;
},
},
});
angular
.
module
(
'app'
,
[])
.
component
(
'annotationHeader'
,
annotationHeader
);
});
beforeEach
(
function
()
{
angular
.
mock
.
module
(
'app'
,
{
groups
:
fakeGroups
,
settings
:
fakeSettings
,
serviceUrl
:
fakeServiceUrl
,
});
angular
.
mock
.
inject
(
function
(
_$componentController_
)
{
$componentController
=
_$componentController_
;
});
});
describe
(
'controller'
,
function
()
{
describe
(
'#htmlLink()'
,
function
()
{
it
(
'returns the HTML link when available'
,
function
()
{
var
ann
=
fixtures
.
defaultAnnotation
();
ann
.
links
=
{
html
:
'https://annotation.service/123'
};
var
ctrl
=
$componentController
(
'annotationHeader'
,
{},
{
annotation
:
ann
,
});
assert
.
equal
(
ctrl
.
htmlLink
(),
ann
.
links
.
html
);
});
it
(
'returns an empty string when no HTML link is available'
,
function
()
{
var
ann
=
fixtures
.
defaultAnnotation
();
ann
.
links
=
{};
var
ctrl
=
$componentController
(
'annotationHeader'
,
{},
{
annotation
:
ann
,
});
assert
.
equal
(
ctrl
.
htmlLink
(),
''
);
});
});
describe
(
'#documentMeta()'
,
function
()
{
it
(
'returns the domain, title link and text for the annotation'
,
function
()
{
var
ann
=
fixtures
.
defaultAnnotation
();
var
ctrl
=
$componentController
(
'annotationHeader'
,
{},
{
annotation
:
ann
,
});
assert
.
deepEqual
(
ctrl
.
documentMeta
(),
fakeDocumentMeta
);
});
});
});
});
src/sidebar/components/test/annotation-test.js
View file @
8e1dfb7a
...
@@ -10,12 +10,6 @@ var util = require('../../directive/test/util');
...
@@ -10,12 +10,6 @@ var util = require('../../directive/test/util');
var
inject
=
angular
.
mock
.
inject
;
var
inject
=
angular
.
mock
.
inject
;
var
fakeDocumentMeta
=
{
domain
:
'docs.io'
,
titleLink
:
'http://docs.io/doc.html'
,
titleText
:
'Dummy title'
,
};
/**
/**
* Returns the annotation directive with helpers stubbed out.
* Returns the annotation directive with helpers stubbed out.
*/
*/
...
@@ -27,11 +21,6 @@ function annotationComponent() {
...
@@ -27,11 +21,6 @@ function annotationComponent() {
'../filter/persona'
:
{
'../filter/persona'
:
{
username
:
noop
,
username
:
noop
,
},
},
'../annotation-metadata'
:
{
domainAndTitle
:
function
(
annot
)
{
// eslint-disable-line no-unused-vars
return
fakeDocumentMeta
;
},
},
});
});
}
}
...
@@ -716,14 +705,6 @@ describe('annotation', function() {
...
@@ -716,14 +705,6 @@ describe('annotation', function() {
});
});
});
});
describe
(
'#documentMeta()'
,
function
()
{
it
(
'returns the domain, title link and text for the annotation'
,
function
()
{
var
annot
=
fixtures
.
defaultAnnotation
();
var
controller
=
createDirective
(
annot
).
controller
;
assert
.
deepEqual
(
controller
.
documentMeta
(),
fakeDocumentMeta
);
});
});
describe
(
'#isDeleted'
,
function
()
{
describe
(
'#isDeleted'
,
function
()
{
it
(
'returns true if the annotation has been marked as deleted'
,
function
()
{
it
(
'returns true if the annotation has been marked as deleted'
,
function
()
{
var
controller
=
createDirective
().
controller
;
var
controller
=
createDirective
().
controller
;
...
@@ -965,12 +946,11 @@ describe('annotation', function() {
...
@@ -965,12 +946,11 @@ describe('annotation', function() {
it
(
'uses the in-context links when available'
,
function
()
{
it
(
'uses the in-context links when available'
,
function
()
{
var
annotation
=
Object
.
assign
({},
fixtures
.
defaultAnnotation
(),
{
var
annotation
=
Object
.
assign
({},
fixtures
.
defaultAnnotation
(),
{
links
:
{
links
:
{
html
:
'https://test.hypothes.is/a/deadbeef'
,
incontext
:
'https://hpt.is/deadbeef'
,
incontext
:
'https://hpt.is/deadbeef'
,
},
},
});
});
var
controller
=
createDirective
(
annotation
).
controller
;
var
controller
=
createDirective
(
annotation
).
controller
;
assert
.
equal
(
controller
.
links
().
incontext
,
annotation
.
links
.
incontext
);
assert
.
equal
(
controller
.
incontextLink
()
,
annotation
.
links
.
incontext
);
});
});
it
(
'falls back to the HTML link when in-context links are missing'
,
function
()
{
it
(
'falls back to the HTML link when in-context links are missing'
,
function
()
{
...
@@ -980,30 +960,13 @@ describe('annotation', function() {
...
@@ -980,30 +960,13 @@ describe('annotation', function() {
},
},
});
});
var
controller
=
createDirective
(
annotation
).
controller
;
var
controller
=
createDirective
(
annotation
).
controller
;
assert
.
equal
(
controller
.
links
().
html
,
annotation
.
links
.
html
);
assert
.
equal
(
controller
.
incontextLink
(),
annotation
.
links
.
html
);
});
it
(
'uses the HTML link when available'
,
function
()
{
var
annotation
=
Object
.
assign
({},
fixtures
.
defaultAnnotation
(),
{
links
:
{
html
:
'https://test.hypothes.is/a/deadbeef'
,
incontext
:
'https://hpt.is/deadbeef'
,
},
});
var
controller
=
createDirective
(
annotation
).
controller
;
assert
.
equal
(
controller
.
links
().
html
,
annotation
.
links
.
html
);
});
});
it
(
'in-context link is blank when unknown'
,
function
()
{
it
(
'in-context link is blank when unknown'
,
function
()
{
var
annotation
=
fixtures
.
defaultAnnotation
();
var
annotation
=
fixtures
.
defaultAnnotation
();
var
controller
=
createDirective
(
annotation
).
controller
;
var
controller
=
createDirective
(
annotation
).
controller
;
assert
.
equal
(
controller
.
links
().
incontext
,
''
);
assert
.
equal
(
controller
.
incontextLink
(),
''
);
});
it
(
'HTML is blank when unknown'
,
function
()
{
var
annotation
=
fixtures
.
defaultAnnotation
();
var
controller
=
createDirective
(
annotation
).
controller
;
assert
.
equal
(
controller
.
links
().
html
,
''
);
});
});
});
});
...
...
src/sidebar/templates/annotation-header.html
0 → 100644
View file @
8e1dfb7a
<header
class=
"annotation-header"
>
<!-- User -->
<span
ng-if=
"vm.user()"
>
<a
class=
"annotation-header__user"
target=
"_blank"
ng-if=
"!vm.isThirdPartyUser()"
ng-href=
"{{vm.serviceUrl('user',{user:vm.user()})}}"
>
{{vm.username()}}
</a>
<span
class=
"annotation-header__user"
ng-if=
"vm.isThirdPartyUser()"
>
{{vm.username()}}
</span>
<span
class=
"annotation-collapsed-replies"
>
<a
class=
"annotation-link"
href=
""
ng-click=
"vm.onReplyCountClick()"
ng-pluralize
count=
"vm.replyCount"
when=
"{'0': '', 'one': '1 reply', 'other': '{} replies'}"
></a>
</span>
<br>
<span
class=
"annotation-header__share-info"
>
<a
class=
"annotation-header__group"
target=
"_blank"
ng-if=
"vm.group() && vm.group().url"
href=
"{{vm.group().url}}"
>
<i
class=
"h-icon-group"
></i><span
class=
"annotation-header__group-name"
>
{{vm.group().name}}
</span>
</a>
<span
ng-show=
"vm.isPrivate"
title=
"This annotation is visible only to you."
>
<i
class=
"h-icon-lock"
></i><span
class=
"annotation-header__group-name"
ng-show=
"!vm.group().url"
>
Only me
</span>
</span>
<i
class=
"h-icon-border-color"
ng-show=
"vm.isHighlight && !vm.isEditing"
title=
"This is a highlight. Click 'edit' to add a note or tag."
></i>
<span
ng-if=
"::vm.showDocumentInfo"
>
<span
class=
"annotation-citation"
ng-if=
"vm.documentMeta().titleLink"
>
on "
<a
ng-href=
"{{vm.documentMeta().titleLink}}"
>
{{vm.documentMeta().titleText}}
</a>
"
</span>
<span
class=
"annotation-citation"
ng-if=
"!vm.documentMeta().titleLink"
>
on "{{vm.documentMeta().titleText}}"
</span>
<span
class=
"annotation-citation-domain"
ng-if=
"vm.documentMeta().domain"
>
({{vm.documentMeta().domain}})
</span>
</span>
</span>
</span>
<span
class=
"u-flex-spacer"
></span>
<timestamp
class-name=
"'annotation-header__timestamp'"
timestamp=
"vm.updated()"
href=
"vm.htmlLink()"
ng-if=
"!vm.editing() && vm.updated()"
></timestamp>
</header>
src/sidebar/templates/annotation.html
View file @
8e1dfb7a
...
@@ -3,55 +3,15 @@
...
@@ -3,55 +3,15 @@
</header>
</header>
<div
ng-keydown=
"vm.onKeydown($event)"
ng-if=
"vm.user()"
>
<div
ng-keydown=
"vm.onKeydown($event)"
ng-if=
"vm.user()"
>
<header
class=
"annotation-header"
>
<!-- User -->
<span
ng-if=
"vm.user()"
>
<a
class=
"annotation-header__user"
target=
"_blank"
ng-if=
"!vm.isThirdPartyUser()"
ng-href=
"{{vm.serviceUrl('user',{user:vm.user()})}}"
>
{{vm.username()}}
</a>
<span
class=
"annotation-header__user"
ng-if=
"vm.isThirdPartyUser()"
>
{{vm.username()}}
</span>
<span
class=
"annotation-collapsed-replies"
>
<a
class=
"annotation-link"
href=
""
ng-click=
"vm.onReplyCountClick()"
ng-pluralize
count=
"vm.replyCount"
when=
"{'0': '', 'one': '1 reply', 'other': '{} replies'}"
></a>
</span>
<br>
<span
class=
"annotation-header__share-info"
>
<a
class=
"annotation-header__group"
target=
"_blank"
ng-if=
"vm.group() && vm.group().url"
href=
"{{vm.group().url}}"
>
<i
class=
"h-icon-group"
></i><span
class=
"annotation-header__group-name"
>
{{vm.group().name}}
</span>
</a>
<span
ng-show=
"vm.state().isPrivate"
title=
"This annotation is visible only to you."
>
<i
class=
"h-icon-lock"
></i><span
class=
"annotation-header__group-name"
ng-show=
"!vm.group().url"
>
Only me
</span>
</span>
<i
class=
"h-icon-border-color"
ng-show=
"vm.isHighlight() && !vm.editing()"
title=
"This is a highlight. Click 'edit' to add a note or tag."
></i>
<span
ng-if=
"::vm.showDocumentInfo"
>
<span
class=
"annotation-citation"
ng-if=
"vm.documentMeta().titleLink"
>
on "
<a
ng-href=
"{{vm.documentMeta().titleLink}}"
>
{{vm.documentMeta().titleText}}
</a>
"
</span>
<span
class=
"annotation-citation"
ng-if=
"!vm.documentMeta().titleLink"
>
on "{{vm.documentMeta().titleText}}"
</span>
<span
class=
"annotation-citation-domain"
ng-if=
"vm.documentMeta().domain"
>
({{vm.documentMeta().domain}})
</span>
</span>
</span>
</span>
<span
class=
"u-flex-spacer"
></span>
<annotation-header
annotation=
"vm.annotation"
is-editing=
"vm.editing()"
<timestamp
is-highlight=
"vm.isHighlight()"
class-name=
"'annotation-header__timestamp'
"
is-private=
"vm.state().isPrivate
"
timestamp=
"vm.updated
()"
on-reply-count-click=
"vm.onReplyCountClick
()"
href=
"vm.links().html
"
reply-count=
"vm.replyCount
"
ng-if=
"!vm.editing() && vm.updated()"
></timestamp
>
show-document-info=
"vm.showDocumentInfo"
>
</header>
</
annotation-
header>
<!-- Excerpts -->
<!-- Excerpts -->
<section
class=
"annotation-quote-list"
<section
class=
"annotation-quote-list"
...
@@ -182,7 +142,7 @@
...
@@ -182,7 +142,7 @@
</button>
</button>
<annotation-share-dialog
<annotation-share-dialog
group=
"vm.group()"
group=
"vm.group()"
uri=
"vm.
links().incontext
"
uri=
"vm.
incontextLink()
"
is-private=
"vm.state().isPrivate"
is-private=
"vm.state().isPrivate"
is-open=
"vm.showShareDialog"
is-open=
"vm.showShareDialog"
on-close=
"vm.showShareDialog = false"
>
on-close=
"vm.showShareDialog = false"
>
...
...
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