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
9cce6a0b
Commit
9cce6a0b
authored
Dec 07, 2015
by
Sean Hammond
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rename model -> domainModel
parent
8925ff91
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
73 additions
and
66 deletions
+73
-66
annotation.js
h/static/scripts/directive/annotation.js
+73
-66
No files found.
h/static/scripts/directive/annotation.js
View file @
9cce6a0b
...
...
@@ -26,21 +26,21 @@ function errorMessage(reason) {
/** Extract a URI, domain and title from the given domain model object.
*
* @param {object}
m
odel An annotation domain model object as received from the
* @param {object}
domainM
odel An annotation domain model object as received from the
* server-side API.
* @returns {object} An object with three properties extracted from the model:
* uri, domain and title.
*
*/
function
extractDocumentMetadata
(
m
odel
)
{
function
extractDocumentMetadata
(
domainM
odel
)
{
var
document_
;
var
uri
=
m
odel
.
uri
;
var
uri
=
domainM
odel
.
uri
;
var
domain
=
new
URL
(
uri
).
hostname
;
if
(
m
odel
.
document
)
{
if
(
domainM
odel
.
document
)
{
if
(
uri
.
indexOf
(
'urn'
)
===
0
)
{
var
i
;
for
(
i
=
0
;
i
<
m
odel
.
document
.
link
.
length
;
i
++
)
{
var
link
=
m
odel
.
document
.
link
[
i
];
for
(
i
=
0
;
i
<
domainM
odel
.
document
.
link
.
length
;
i
++
)
{
var
link
=
domainM
odel
.
document
.
link
[
i
];
if
(
link
.
href
.
indexOf
(
'urn:'
)
===
0
)
{
continue
;
}
...
...
@@ -49,8 +49,12 @@ function extractDocumentMetadata(model) {
}
}
var
documentTitle
=
Array
.
isArray
(
model
.
document
.
title
)
?
model
.
document
.
title
[
0
]
:
model
.
document
.
title
;
var
documentTitle
;
if
(
Array
.
isArray
(
domainModel
.
document
.
title
))
{
documentTitle
=
domainModel
.
document
.
title
[
0
];
}
else
{
documentTitle
=
domainModel
.
document
.
title
;
}
document_
=
{
uri
:
uri
,
...
...
@@ -106,12 +110,12 @@ function updateDomainModel(domainModel, vm) {
}
/** Update the view model from the domain model changes. */
function
updateViewModel
(
drafts
,
m
odel
,
vm
)
{
var
draft
=
drafts
.
get
(
m
odel
);
function
updateViewModel
(
drafts
,
domainM
odel
,
vm
)
{
var
draft
=
drafts
.
get
(
domainM
odel
);
// Extend the view model with a copy of the domain model.
// Note that copy is used so that deep properties aren't shared.
vm
.
annotation
=
angular
.
extend
({},
angular
.
copy
(
m
odel
));
vm
.
annotation
=
angular
.
extend
({},
angular
.
copy
(
domainM
odel
));
// If we have unsaved changes to this annotation, apply them
// to the view model.
...
...
@@ -122,7 +126,7 @@ function updateViewModel(drafts, model, vm) {
vm
.
annotationURI
=
new
URL
(
'/a/'
+
vm
.
annotation
.
id
,
vm
.
baseURI
).
href
;
vm
.
document
=
extractDocumentMetadata
(
m
odel
);
vm
.
document
=
extractDocumentMetadata
(
domainM
odel
);
// Form the tags for ngTagsInput.
vm
.
annotation
.
tags
=
(
vm
.
annotation
.
tags
||
[]).
map
(
function
(
tag
)
{
...
...
@@ -183,7 +187,7 @@ function AnnotationController(
tags
,
time
)
{
var
vm
=
this
;
var
m
odel
;
var
domainM
odel
;
var
newlyCreatedByHighlightButton
;
/**
...
...
@@ -230,7 +234,7 @@ function AnnotationController(
* haven't been saved yet - the data that will be saved to the server when
* they are saved).
*/
m
odel
=
$scope
.
annotationGet
();
domainM
odel
=
$scope
.
annotationGet
();
/**
* `true` if this AnnotationController instance was created as a result of
...
...
@@ -240,22 +244,25 @@ function AnnotationController(
* or annotation that was fetched from the server (as opposed to created
* new client-side).
*/
newlyCreatedByHighlightButton
=
m
odel
.
$highlight
||
false
;
newlyCreatedByHighlightButton
=
domainM
odel
.
$highlight
||
false
;
// Call `onDestroy()` when this AnnotationController's scope is removed.
$scope
.
$on
(
'$destroy'
,
onDestroy
);
// Call `onModelChange()` whenever `model` changes.
$scope
.
$watch
((
function
()
{
return
model
;}),
onModelChange
,
true
);
// Call `onDomainModelChange()` whenever `domainModel` changes.
$scope
.
$watch
(
function
()
{
return
domainModel
;},
onDomainModelChange
,
true
);
// Call `onGroupFocused()` whenever the currently-focused group changes.
$scope
.
$on
(
events
.
GROUP_FOCUSED
,
onGroupFocused
);
// New annotations (just created locally by the client, rather then
// received from the server) have some fields missing. Add them.
model
.
user
=
model
.
user
||
session
.
state
.
userid
;
model
.
group
=
model
.
group
||
groups
.
focused
().
id
;
model
.
permissions
=
model
.
permissions
||
permissions
[
'default'
](
model
.
group
);
domainModel
.
user
=
domainModel
.
user
||
session
.
state
.
userid
;
domainModel
.
group
=
domainModel
.
group
||
groups
.
focused
().
id
;
if
(
!
domainModel
.
permissions
)
{
domainModel
.
permissions
=
permissions
[
'default'
](
domainModel
.
group
);
}
// Automatically save new highlights to the server when they're created.
// Note that this line also gets called when the user logs in (since
...
...
@@ -268,7 +275,7 @@ function AnnotationController(
// created by the annotate button) or it has edits not yet saved to the
// server - then open the editor on AnnotationController instantiation.
if
(
!
newlyCreatedByHighlightButton
)
{
if
(
isNew
(
model
)
||
drafts
.
get
(
m
odel
))
{
if
(
isNew
(
domainModel
)
||
drafts
.
get
(
domainM
odel
))
{
vm
.
edit
();
}
}
...
...
@@ -287,7 +294,7 @@ function AnnotationController(
// Move any new annotations to the currently focused group when
// switching groups. See GH #2689 for context.
if
(
isNew
(
m
odel
))
{
if
(
isNew
(
domainM
odel
))
{
var
newGroup
=
groups
.
focused
().
id
;
var
isShared
=
permissions
.
isShared
(
vm
.
annotation
.
permissions
,
vm
.
annotation
.
group
);
...
...
@@ -297,22 +304,22 @@ function AnnotationController(
vm
.
annotation
.
group
=
newGroup
;
}
if
(
drafts
.
get
(
m
odel
))
{
if
(
drafts
.
get
(
domainM
odel
))
{
var
draftDomainModel
=
{};
updateDomainModel
(
draftDomainModel
,
vm
.
annotation
);
updateDraft
(
draftDomainModel
);
}
}
/** Called whenever `
m
odel` changes. */
function
on
ModelChange
(
m
odel
,
old
)
{
if
(
m
odel
.
updated
!==
old
.
updated
)
{
/** Called whenever `
domainM
odel` changes. */
function
on
DomainModelChange
(
domainM
odel
,
old
)
{
if
(
domainM
odel
.
updated
!==
old
.
updated
)
{
// Discard saved drafts.
drafts
.
remove
(
m
odel
);
drafts
.
remove
(
domainM
odel
);
}
updateTimestamp
(
m
odel
===
old
);
// Repeat on first run.
updateViewModel
(
drafts
,
m
odel
,
vm
);
updateTimestamp
(
domainM
odel
===
old
);
// Repeat on first run.
updateViewModel
(
drafts
,
domainM
odel
,
vm
);
}
...
...
@@ -327,7 +334,7 @@ function AnnotationController(
*
*/
function
saveNewHighlight
()
{
if
(
!
isNew
(
m
odel
))
{
if
(
!
isNew
(
domainM
odel
))
{
// Already saved.
return
;
}
...
...
@@ -337,16 +344,16 @@ function AnnotationController(
return
;
}
if
(
m
odel
.
user
)
{
if
(
domainM
odel
.
user
)
{
// User is logged in, save to server.
// Highlights are always private.
m
odel
.
permissions
=
permissions
.
private
();
m
odel
.
$create
().
then
(
function
()
{
$rootScope
.
$emit
(
'annotationCreated'
,
m
odel
);
domainM
odel
.
permissions
=
permissions
.
private
();
domainM
odel
.
$create
().
then
(
function
()
{
$rootScope
.
$emit
(
'annotationCreated'
,
domainM
odel
);
});
}
else
{
// User isn't logged in, save to drafts.
updateDraft
(
m
odel
);
updateDraft
(
domainM
odel
);
}
}
...
...
@@ -368,7 +375,7 @@ function AnnotationController(
if
(
draft
.
permissions
)
{
changes
.
permissions
=
draft
.
permissions
;
}
drafts
.
update
(
m
odel
,
changes
);
drafts
.
update
(
domainM
odel
,
changes
);
}
// We use `var foo = function() {...}` here instead of `function foo() {...}`
...
...
@@ -378,17 +385,17 @@ function AnnotationController(
// New (not yet saved to the server) annotations don't have any .updated
// yet, so we can't update their timestamp.
if
(
!
m
odel
.
updated
)
{
if
(
!
domainM
odel
.
updated
)
{
return
;
}
vm
.
timestamp
=
time
.
toFuzzyString
(
m
odel
.
updated
);
vm
.
timestamp
=
time
.
toFuzzyString
(
domainM
odel
.
updated
);
if
(
!
repeat
)
{
return
;
}
var
fuzzyUpdate
=
time
.
nextFuzzyUpdate
(
m
odel
.
updated
);
var
fuzzyUpdate
=
time
.
nextFuzzyUpdate
(
domainM
odel
.
updated
);
var
nextUpdate
=
(
1000
*
fuzzyUpdate
)
+
500
;
$timeout
(
function
()
{
...
...
@@ -419,7 +426,7 @@ function AnnotationController(
// performance bottleneck and we would need to get the id token into the
// session, which we should probably do anyway (and move to opaque bearer
// tokens for the access token).
return
permissions
.
permits
(
action
,
m
odel
,
session
.
state
.
userid
);
return
permissions
.
permits
(
action
,
domainM
odel
,
session
.
state
.
userid
);
};
/**
...
...
@@ -436,7 +443,7 @@ function AnnotationController(
errorMessage
(
reason
),
'Deleting annotation failed'
);
};
$scope
.
$apply
(
function
()
{
annotationMapper
.
deleteAnnotation
(
m
odel
).
then
(
annotationMapper
.
deleteAnnotation
(
domainM
odel
).
then
(
null
,
onRejected
);
});
}
...
...
@@ -449,10 +456,10 @@ function AnnotationController(
* @description Switches the view to an editor.
*/
vm
.
edit
=
function
()
{
if
(
!
drafts
.
get
(
m
odel
))
{
updateDraft
(
m
odel
);
if
(
!
drafts
.
get
(
domainM
odel
))
{
updateDraft
(
domainM
odel
);
}
vm
.
action
=
isNew
(
m
odel
)
?
'create'
:
'edit'
;
vm
.
action
=
isNew
(
domainM
odel
)
?
'create'
:
'edit'
;
};
/**
...
...
@@ -509,16 +516,16 @@ function AnnotationController(
vm
.
isHighlight
=
function
()
{
if
(
newlyCreatedByHighlightButton
)
{
return
true
;
}
else
if
(
isNew
(
m
odel
))
{
}
else
if
(
isNew
(
domainM
odel
))
{
return
false
;
}
else
{
// Once an annotation has been saved to the server there's no longer a
// simple property that says whether it's a highlight or not. For
// example there's no
m
odel.highlight: true. Instead a highlight is
// example there's no
domainM
odel.highlight: true. Instead a highlight is
// defined as an annotation that isn't a page note or a reply and that
// has no text or tags.
var
isPageNote
=
(
m
odel
.
target
||
[]).
length
===
0
;
var
isReply
=
(
m
odel
.
references
||
[]).
length
!==
0
;
var
isPageNote
=
(
domainM
odel
.
target
||
[]).
length
===
0
;
var
isReply
=
(
domainM
odel
.
references
||
[]).
length
!==
0
;
return
(
!
isPageNote
&&
!
isReply
&&
!
vm
.
hasContent
());
}
};
...
...
@@ -529,7 +536,7 @@ function AnnotationController(
* @returns {boolean} True if the annotation is private to the current user.
*/
vm
.
isPrivate
=
function
()
{
return
permissions
.
isPrivate
(
vm
.
annotation
.
permissions
,
m
odel
.
user
);
return
permissions
.
isPrivate
(
vm
.
annotation
.
permissions
,
domainM
odel
.
user
);
};
/**
...
...
@@ -558,7 +565,7 @@ function AnnotationController(
* Creates a new message in reply to this annotation.
*/
vm
.
reply
=
function
()
{
var
references
=
m
odel
.
references
||
[];
var
references
=
domainM
odel
.
references
||
[];
// TODO: Remove this check once we have server-side code to ensure that
// references is always an array of strings.
...
...
@@ -566,16 +573,16 @@ function AnnotationController(
references
=
[
references
];
}
references
=
references
.
concat
(
m
odel
.
id
);
references
=
references
.
concat
(
domainM
odel
.
id
);
var
reply
=
annotationMapper
.
createAnnotation
({
references
:
references
,
uri
:
m
odel
.
uri
uri
:
domainM
odel
.
uri
});
reply
.
group
=
m
odel
.
group
;
reply
.
group
=
domainM
odel
.
group
;
if
(
session
.
state
.
userid
)
{
if
(
permissions
.
isShared
(
model
.
permissions
,
m
odel
.
group
))
{
if
(
permissions
.
isShared
(
domainModel
.
permissions
,
domainM
odel
.
group
))
{
reply
.
permissions
=
permissions
.
shared
(
reply
.
group
);
}
else
{
reply
.
permissions
=
permissions
.
private
();
...
...
@@ -589,11 +596,11 @@ function AnnotationController(
* @description Reverts an edit in progress and returns to the viewer.
*/
vm
.
revert
=
function
()
{
drafts
.
remove
(
m
odel
);
drafts
.
remove
(
domainM
odel
);
if
(
vm
.
action
===
'create'
)
{
$rootScope
.
$emit
(
'annotationDeleted'
,
m
odel
);
$rootScope
.
$emit
(
'annotationDeleted'
,
domainM
odel
);
}
else
{
updateViewModel
(
drafts
,
m
odel
,
vm
);
updateViewModel
(
drafts
,
domainM
odel
,
vm
);
view
();
}
};
...
...
@@ -604,7 +611,7 @@ function AnnotationController(
* @description Saves any edits and returns to the viewer.
*/
vm
.
save
=
function
()
{
if
(
!
m
odel
.
user
)
{
if
(
!
domainM
odel
.
user
)
{
return
flash
.
info
(
'Please sign in to save your annotations.'
);
}
...
...
@@ -614,30 +621,30 @@ function AnnotationController(
// Update stored tags with the new tags of this annotation.
var
newTags
=
vm
.
annotation
.
tags
.
filter
(
function
(
tag
)
{
var
tags
=
m
odel
.
tags
||
[];
var
tags
=
domainM
odel
.
tags
||
[];
return
tags
.
indexOf
(
tag
.
text
)
===
-
1
;
});
tags
.
store
(
newTags
);
switch
(
vm
.
action
)
{
case
'create'
:
updateDomainModel
(
m
odel
,
vm
.
annotation
);
updateDomainModel
(
domainM
odel
,
vm
.
annotation
);
var
onFulfilled
=
function
()
{
$rootScope
.
$emit
(
'annotationCreated'
,
m
odel
);
$rootScope
.
$emit
(
'annotationCreated'
,
domainM
odel
);
view
();
};
var
onRejected
=
function
(
reason
)
{
flash
.
error
(
errorMessage
(
reason
),
'Saving annotation failed'
);
};
return
m
odel
.
$create
().
then
(
onFulfilled
,
onRejected
);
return
domainM
odel
.
$create
().
then
(
onFulfilled
,
onRejected
);
case
'edit'
:
var
updatedModel
=
angular
.
copy
(
m
odel
);
var
updatedModel
=
angular
.
copy
(
domainM
odel
);
updateDomainModel
(
updatedModel
,
vm
.
annotation
);
onFulfilled
=
function
()
{
angular
.
copy
(
updatedModel
,
m
odel
);
$rootScope
.
$emit
(
'annotationUpdated'
,
m
odel
);
angular
.
copy
(
updatedModel
,
domainM
odel
);
$rootScope
.
$emit
(
'annotationUpdated'
,
domainM
odel
);
view
();
};
onRejected
=
function
(
reason
)
{
...
...
@@ -666,7 +673,7 @@ function AnnotationController(
// creating or editing, we cache that and use the same privacy level the
// next time they create an annotation.
// But _don't_ cache it when they change the privacy level of a reply.
if
(
!
m
odel
.
references
)
{
// If the annotation is not a reply.
if
(
!
domainM
odel
.
references
)
{
// If the annotation is not a reply.
permissions
.
setDefault
(
privacy
);
}
if
(
privacy
===
'private'
)
{
...
...
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