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
0565f6af
Commit
0565f6af
authored
Jan 20, 2015
by
Randall Leeds
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1872 from hypothesis/url-fragments
Remove URL fragments
parents
0a0019ec
c8f684b2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
364 additions
and
3 deletions
+364
-3
fragmentselector.coffee
h/static/scripts/annotator/plugin/fragmentselector.coffee
+18
-0
guest.coffee
h/static/scripts/guest.coffee
+22
-3
url.js
h/static/scripts/vendor/polyfills/url.js
+324
-0
No files found.
h/static/scripts/annotator/plugin/fragmentselector.coffee
0 → 100644
View file @
0565f6af
# Annotator plugin for creating the Fragment Selector
class
Annotator
.
Plugin
.
FragmentSelector
extends
Annotator
.
Plugin
pluginInit
:
->
# Register the creator Fragment selectors
@
annotator
.
anchoring
.
selectorCreators
.
push
name
:
"FragmentSelector"
describe
:
@
_getFragmentSelector
# Create a FragmentSelector around a range
_getFragmentSelector
:
(
annotation
,
target
)
=>
fragment
=
(
new
URL
(
@
annotator
.
getRawHref
())).
hash
[
type
:
"FragmentSelector"
value
:
fragment
]
h/static/scripts/guest.coffee
View file @
0565f6af
...
...
@@ -23,6 +23,7 @@ class Annotator.Guest extends Annotator
TextPosition
:
{}
TextQuote
:
{}
FuzzyTextAnchors
:
{}
FragmentSelector
:
{}
# Internal state
tool
:
'comment'
...
...
@@ -119,9 +120,27 @@ class Annotator.Guest extends Annotator
# Announce the new positions, so that the sidebar knows
this
.
plugins
.
Bridge
.
sync
([
highlight
.
annotation
])
# Utility function to remove the hash part from a URL
_removeHash
:
(
url
)
->
url
=
new
URL
url
url
.
hash
=
""
url
.
toString
()
# Utility function to get the decoded form of the document URI
getHref
:
=>
@
plugins
.
PDF
?
.
uri
()
?
@
plugins
.
Document
.
uri
()
?
super
getRawHref
:
->
if
@
plugins
.
PDF
@
plugins
.
PDF
.
uri
()
else
@
plugins
.
Document
.
uri
()
# Utility function to get a de-hashed form of the document URI
getHref
:
->
@
_removeHash
@
getRawHref
()
# Utility function to filter metadata and de-hash the URIs
getMetadata
:
=>
metadata
=
@
plugins
.
Document
?
.
metadata
metadata
.
link
?
.
forEach
(
link
)
=>
link
.
href
=
@
_removeHash
link
.
href
metadata
_setupXDM
:
(
options
)
->
# jschannel chokes FF and Chrome extension origins.
...
...
@@ -160,7 +179,7 @@ class Annotator.Guest extends Annotator
.
catch
(
problem
)
=>
trans
.
complete
uri
:
@
getHref
()
metadata
:
@
plugins
.
Document
?
.
metadata
metadata
:
@
getMetadata
()
trans
.
delayReturn
(
true
)
)
...
...
h/static/scripts/vendor/polyfills/url.js
0 → 100644
View file @
0565f6af
// URL Polyfill
// Draft specification: http://url.spec.whatwg.org
// Notes:
// - Primarily useful for parsing URLs and modifying query parameters
// - Should work in IE8+ and everything more modern
(
function
(
global
)
{
'use strict'
;
// Browsers may have:
// * No global URL object
// * URL with static methods only - may have a dummy constructor
// * URL with members except searchParams
// * Full URL API support
var
origURL
=
global
.
URL
;
var
nativeURL
;
try
{
if
(
origURL
)
{
nativeURL
=
new
global
.
URL
(
'http://example.com'
);
if
(
'searchParams'
in
nativeURL
)
return
;
if
(
!
(
'href'
in
nativeURL
))
nativeURL
=
undefined
;
}
}
catch
(
_
)
{}
function
URLUtils
(
url
)
{
if
(
nativeURL
)
return
new
origURL
(
url
);
var
anchor
=
document
.
createElement
(
'a'
);
anchor
.
href
=
url
;
return
anchor
;
}
global
.
URL
=
function
URL
(
url
,
base
)
{
if
(
!
(
this
instanceof
global
.
URL
))
throw
new
TypeError
(
"Failed to construct 'URL': Please use the 'new' operator."
);
if
(
base
)
{
url
=
(
function
()
{
if
(
nativeURL
)
return
new
origURL
(
url
,
base
).
href
;
var
doc
;
// Use another document/base tag/anchor for relative URL resolution, if possible
if
(
document
.
implementation
&&
document
.
implementation
.
createHTMLDocument
)
{
doc
=
document
.
implementation
.
createHTMLDocument
(
''
);
}
else
if
(
document
.
implementation
&&
document
.
implementation
.
createDocument
)
{
doc
=
document
.
implementation
.
createElement
(
'http://www.w3.org/1999/xhtml'
,
'html'
,
null
);
doc
.
documentElement
.
appendChild
(
doc
.
createElement
(
'head'
));
doc
.
documentElement
.
appendChild
(
doc
.
createElement
(
'body'
));
}
else
if
(
window
.
ActiveXObject
)
{
doc
=
new
window
.
ActiveXObject
(
'htmlfile'
);
doc
.
write
(
'<head></head><body></body>'
);
doc
.
close
();
}
if
(
!
doc
)
throw
Error
(
'base not supported'
);
var
baseTag
=
doc
.
createElement
(
'base'
);
baseTag
.
href
=
base
;
doc
.
getElementsByTagName
(
'head'
)[
0
].
appendChild
(
baseTag
);
var
anchor
=
doc
.
createElement
(
'a'
);
anchor
.
href
=
url
;
return
anchor
.
href
;
}());
}
// An inner object implementing URLUtils (either a native URL
// object or an HTMLAnchorElement instance) is used to perform the
// URL algorithms. With full ES5 getter/setter support, return a
// regular object For IE8's limited getter/setter support, a
// different HTMLAnchorElement is returned with properties
// overridden
var
instance
=
URLUtils
(
url
||
''
);
// Detect for ES5 getter/setter support
var
ES5_GET_SET
=
(
Object
.
defineProperties
&&
(
function
()
{
var
o
=
{};
Object
.
defineProperties
(
o
,
{
p
:
{
'get'
:
function
()
{
return
true
;
}
}
});
return
o
.
p
;
}()));
var
self
=
ES5_GET_SET
?
this
:
document
.
createElement
(
'a'
);
// NOTE: Doesn't do the encoding/decoding dance
function
parse
(
input
,
isindex
)
{
var
sequences
=
input
.
split
(
'&'
);
if
(
isindex
&&
sequences
[
0
].
indexOf
(
'='
)
===
-
1
)
sequences
[
0
]
=
'='
+
sequences
[
0
];
var
pairs
=
[];
sequences
.
forEach
(
function
(
bytes
)
{
if
(
bytes
.
length
===
0
)
return
;
var
index
=
bytes
.
indexOf
(
'='
);
if
(
index
!==
-
1
)
{
var
name
=
bytes
.
substring
(
0
,
index
);
var
value
=
bytes
.
substring
(
index
+
1
);
}
else
{
name
=
bytes
;
value
=
''
;
}
name
=
name
.
replace
(
/
\+
/g
,
' '
);
value
=
value
.
replace
(
/
\+
/g
,
' '
);
pairs
.
push
({
name
:
name
,
value
:
value
});
});
var
output
=
[];
pairs
.
forEach
(
function
(
pair
)
{
output
.
push
({
name
:
decodeURIComponent
(
pair
.
name
),
value
:
decodeURIComponent
(
pair
.
value
)
});
});
return
output
;
}
function
URLSearchParams
(
url_object
,
init
)
{
var
pairs
=
[];
if
(
init
)
pairs
=
parse
(
init
);
this
.
_setPairs
=
function
(
list
)
{
pairs
=
list
;
};
this
.
_updateSteps
=
function
()
{
updateSteps
();
};
var
updating
=
false
;
function
updateSteps
()
{
if
(
updating
)
return
;
updating
=
true
;
// TODO: For all associated url objects
url_object
.
search
=
serialize
(
pairs
);
updating
=
false
;
}
// NOTE: Doesn't do the encoding/decoding dance
function
serialize
(
pairs
)
{
var
output
=
''
,
first
=
true
;
pairs
.
forEach
(
function
(
pair
)
{
var
name
=
encodeURIComponent
(
pair
.
name
);
var
value
=
encodeURIComponent
(
pair
.
value
);
if
(
!
first
)
output
+=
'&'
;
output
+=
name
+
'='
+
value
;
first
=
false
;
});
return
output
.
replace
(
/%20/g
,
'+'
);
}
Object
.
defineProperties
(
this
,
{
append
:
{
value
:
function
(
name
,
value
)
{
pairs
.
push
({
name
:
name
,
value
:
value
});
updateSteps
();
}
},
'delete'
:
{
value
:
function
(
name
)
{
for
(
var
i
=
0
;
i
<
pairs
.
length
;)
{
if
(
pairs
[
i
].
name
===
name
)
pairs
.
splice
(
i
,
1
);
else
++
i
;
}
updateSteps
();
}
},
get
:
{
value
:
function
(
name
)
{
for
(
var
i
=
0
;
i
<
pairs
.
length
;
++
i
)
{
if
(
pairs
[
i
].
name
===
name
)
return
pairs
[
i
].
value
;
}
return
null
;
}
},
getAll
:
{
value
:
function
(
name
)
{
var
result
=
[];
for
(
var
i
=
0
;
i
<
pairs
.
length
;
++
i
)
{
if
(
pairs
[
i
].
name
===
name
)
result
.
push
(
pairs
[
i
].
value
);
}
return
result
;
}
},
has
:
{
value
:
function
(
name
)
{
for
(
var
i
=
0
;
i
<
pairs
.
length
;
++
i
)
{
if
(
pairs
[
i
].
name
===
name
)
return
true
;
}
return
false
;
}
},
set
:
{
value
:
function
(
name
,
value
)
{
var
found
=
false
;
for
(
var
i
=
0
;
i
<
pairs
.
length
;)
{
if
(
pairs
[
i
].
name
===
name
)
{
if
(
!
found
)
{
pairs
[
i
].
value
=
value
;
found
=
true
;
++
i
;
}
else
{
pairs
.
splice
(
i
,
1
);
}
}
else
{
++
i
;
}
}
if
(
!
found
)
pairs
.
push
({
name
:
name
,
value
:
value
});
updateSteps
();
}
},
toString
:
{
value
:
function
()
{
return
serialize
(
pairs
);
}
}
});
};
var
queryObject
=
new
URLSearchParams
(
self
,
instance
.
search
?
instance
.
search
.
substring
(
1
)
:
null
);
Object
.
defineProperties
(
self
,
{
href
:
{
get
:
function
()
{
return
instance
.
href
;
},
set
:
function
(
v
)
{
instance
.
href
=
v
;
tidy_instance
();
update_steps
();
}
},
origin
:
{
get
:
function
()
{
if
(
'origin'
in
instance
)
return
instance
.
origin
;
return
this
.
protocol
+
'//'
+
this
.
host
;
}
},
protocol
:
{
get
:
function
()
{
return
instance
.
protocol
;
},
set
:
function
(
v
)
{
instance
.
protocol
=
v
;
}
},
username
:
{
get
:
function
()
{
return
instance
.
username
;
},
set
:
function
(
v
)
{
instance
.
username
=
v
;
}
},
password
:
{
get
:
function
()
{
return
instance
.
password
;
},
set
:
function
(
v
)
{
instance
.
password
=
v
;
}
},
host
:
{
get
:
function
()
{
// IE returns default port in |host|
var
re
=
{
'http:'
:
/
:
80
$
/
,
'https:'
:
/
:
443
$
/
,
'ftp:'
:
/
:
21
$
/
}[
instance
.
protocol
];
return
re
?
instance
.
host
.
replace
(
re
,
''
)
:
instance
.
host
;
},
set
:
function
(
v
)
{
instance
.
host
=
v
;
}
},
hostname
:
{
get
:
function
()
{
return
instance
.
hostname
;
},
set
:
function
(
v
)
{
instance
.
hostname
=
v
;
}
},
port
:
{
get
:
function
()
{
return
instance
.
port
;
},
set
:
function
(
v
)
{
instance
.
port
=
v
;
}
},
pathname
:
{
get
:
function
()
{
// IE does not include leading '/' in |pathname|
if
(
instance
.
pathname
.
charAt
(
0
)
!==
'/'
)
return
'/'
+
instance
.
pathname
;
return
instance
.
pathname
;
},
set
:
function
(
v
)
{
instance
.
pathname
=
v
;
}
},
search
:
{
get
:
function
()
{
return
instance
.
search
;
},
set
:
function
(
v
)
{
if
(
instance
.
search
===
v
)
return
;
instance
.
search
=
v
;
tidy_instance
();
update_steps
();
}
},
searchParams
:
{
get
:
function
()
{
return
queryObject
;
}
// TODO: implement setter
},
hash
:
{
get
:
function
()
{
return
instance
.
hash
;
},
set
:
function
(
v
)
{
instance
.
hash
=
v
;
tidy_instance
();
}
},
toString
:
{
value
:
function
()
{
return
instance
.
toString
();
}
},
valueOf
:
{
value
:
function
()
{
return
instance
.
valueOf
();
}
}
});
function
tidy_instance
()
{
var
href
=
instance
.
href
.
replace
(
/#$|
\?
$|
\?(?=
#
)
/g
,
''
);
if
(
instance
.
href
!==
href
)
instance
.
href
=
href
;
}
function
update_steps
()
{
queryObject
.
_setPairs
(
instance
.
search
?
parse
(
instance
.
search
.
substring
(
1
))
:
[]);
queryObject
.
_updateSteps
();
};
return
self
;
};
if
(
origURL
)
{
for
(
var
i
in
origURL
)
{
if
(
origURL
.
hasOwnProperty
(
i
))
global
.
URL
[
i
]
=
origURL
[
i
];
}
}
}(
this
));
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