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
12d49902
Commit
12d49902
authored
Mar 27, 2017
by
Sean Hammond
Committed by
GitHub
Mar 27, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #307 from hypothesis/excerpt-component
Convert `<excerpt>` to a component
parents
ce2509ba
45f09724
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
202 additions
and
213 deletions
+202
-213
app.js
src/sidebar/app.js
+2
-2
excerpt.js
src/sidebar/components/excerpt.js
+179
-0
excerpt-test.js
src/sidebar/components/test/excerpt-test.js
+21
-21
excerpt.js
src/sidebar/directive/excerpt.js
+0
-190
excerpt-overflow-monitor.js
src/sidebar/util/excerpt-overflow-monitor.js
+0
-0
excerpt-overflow-monitor-test.js
src/sidebar/util/test/excerpt-overflow-monitor-test.js
+0
-0
No files found.
src/sidebar/app.js
View file @
12d49902
...
...
@@ -140,6 +140,7 @@ module.exports = angular.module('h', [
.
component
(
'annotationShareDialog'
,
require
(
'./components/annotation-share-dialog'
))
.
component
(
'annotationThread'
,
require
(
'./components/annotation-thread'
))
.
component
(
'dropdownMenuBtn'
,
require
(
'./components/dropdown-menu-btn'
))
.
component
(
'excerpt'
,
require
(
'./components/excerpt'
))
.
component
(
'groupList'
,
require
(
'./components/group-list'
))
.
component
(
'helpLink'
,
require
(
'./components/help-link'
))
.
component
(
'helpPanel'
,
require
(
'./components/help-panel'
))
...
...
@@ -163,7 +164,6 @@ module.exports = angular.module('h', [
.
directive
(
'markdown'
,
require
(
'./directive/markdown'
))
.
directive
(
'topBar'
,
require
(
'./directive/top-bar'
))
.
directive
(
'excerpt'
,
require
(
'./directive/excerpt'
).
directive
)
.
directive
(
'formInput'
,
require
(
'./directive/form-input'
))
.
directive
(
'formValidate'
,
require
(
'./directive/form-validate'
))
.
directive
(
'hAutofocus'
,
require
(
'./directive/h-autofocus'
))
...
...
@@ -202,7 +202,7 @@ module.exports = angular.module('h', [
.
factory
(
'store'
,
require
(
'./store'
))
.
value
(
'Discovery'
,
require
(
'../shared/discovery'
))
.
value
(
'ExcerptOverflowMonitor'
,
require
(
'./
directive
/excerpt-overflow-monitor'
))
.
value
(
'ExcerptOverflowMonitor'
,
require
(
'./
util
/excerpt-overflow-monitor'
))
.
value
(
'VirtualThreadList'
,
require
(
'./virtual-thread-list'
))
.
value
(
'raven'
,
require
(
'./raven'
))
.
value
(
'settings'
,
settings
)
...
...
src/sidebar/components/excerpt.js
0 → 100644
View file @
12d49902
'use strict'
;
// @ngInject
function
ExcerptController
(
$element
,
$scope
,
ExcerptOverflowMonitor
)
{
var
self
=
this
;
if
(
this
.
collapse
===
undefined
)
{
this
.
collapse
=
true
;
}
if
(
this
.
animate
===
undefined
)
{
this
.
animate
=
true
;
}
if
(
this
.
enabled
===
undefined
)
{
this
.
enabled
=
true
;
}
this
.
isExpandable
=
function
()
{
return
this
.
overflowing
&&
this
.
collapse
;
};
this
.
isCollapsible
=
function
()
{
return
this
.
overflowing
&&
!
this
.
collapse
;
};
this
.
toggle
=
function
(
event
)
{
// When the user clicks a link explicitly to toggle the collapsed state,
// the event is not propagated.
event
.
stopPropagation
();
this
.
collapse
=
!
this
.
collapse
;
};
this
.
expand
=
function
()
{
// When the user expands the excerpt 'implicitly' by clicking at the bottom
// of the collapsed excerpt, the event is allowed to propagate. For
// annotation cards, this causes clicking on a quote to scroll the view to
// the selected annotation.
this
.
collapse
=
false
;
};
this
.
showInlineControls
=
function
()
{
return
this
.
overflowing
&&
this
.
inlineControls
;
};
this
.
bottomShadowStyles
=
function
()
{
return
{
'excerpt__shadow'
:
true
,
'excerpt__shadow--transparent'
:
this
.
inlineControls
,
'is-hidden'
:
!
this
.
isExpandable
(),
};
};
// Test if the element or any of its parents have been hidden by
// an 'ng-show' directive
function
isElementHidden
()
{
var
el
=
$element
[
0
];
while
(
el
)
{
if
(
el
.
classList
.
contains
(
'ng-hide'
))
{
return
true
;
}
el
=
el
.
parentElement
;
}
return
false
;
}
var
overflowMonitor
=
new
ExcerptOverflowMonitor
({
getState
:
function
()
{
return
{
enabled
:
self
.
enabled
,
animate
:
self
.
animate
,
collapsedHeight
:
self
.
collapsedHeight
,
collapse
:
self
.
collapse
,
overflowHysteresis
:
self
.
overflowHysteresis
,
};
},
contentHeight
:
function
()
{
var
contentElem
=
$element
[
0
].
querySelector
(
'.excerpt'
);
if
(
!
contentElem
)
{
return
null
;
}
return
contentElem
.
scrollHeight
;
},
onOverflowChanged
:
function
(
overflowing
)
{
self
.
overflowing
=
overflowing
;
if
(
self
.
onCollapsibleChanged
)
{
self
.
onCollapsibleChanged
({
collapsible
:
overflowing
});
}
// Even though this change happens outside the framework, we use
// $digest() rather than $apply() here to avoid a large number of full
// digest cycles if many excerpts update their overflow state at the
// same time. The onCollapsibleChanged() handler, if any, is
// responsible for triggering any necessary digests in parent scopes.
$scope
.
$digest
();
},
},
window
.
requestAnimationFrame
);
this
.
contentStyle
=
overflowMonitor
.
contentStyle
;
// Listen for document events which might affect whether the excerpt
// is overflowing, even if its content has not changed.
$element
[
0
].
addEventListener
(
'load'
,
overflowMonitor
.
check
,
false
/* capture */
);
window
.
addEventListener
(
'resize'
,
overflowMonitor
.
check
);
$scope
.
$on
(
'$destroy'
,
function
()
{
window
.
removeEventListener
(
'resize'
,
overflowMonitor
.
check
);
});
// Watch for changes to the visibility of the excerpt.
// Unfortunately there is no DOM API for this, so we rely on a digest
// being triggered after the visibility changes.
$scope
.
$watch
(
isElementHidden
,
function
(
hidden
)
{
if
(
!
hidden
)
{
overflowMonitor
.
check
();
}
});
// Watch input properties which may affect the overflow state
$scope
.
$watch
(
'vm.contentData'
,
overflowMonitor
.
check
);
$scope
.
$watch
(
'vm.enabled'
,
overflowMonitor
.
check
);
// Trigger an initial calculation of the overflow state.
//
// This is performed asynchronously so that the content of the <excerpt>
// has settled - ie. all Angular directives have been fully applied and
// the DOM has stopped changing. This may take several $digest cycles.
overflowMonitor
.
check
();
}
/**
* @description This component truncates the height of its contents to a
* specified number of lines and provides controls for expanding
* and collapsing the resulting truncated element.
*/
module
.
exports
=
{
controller
:
ExcerptController
,
controllerAs
:
'vm'
,
bindings
:
{
/** Whether or not expansion should be animated. Defaults to true. */
animate
:
'<?'
,
/**
* The data which is used to generate the excerpt's content.
* When this changes, the excerpt will recompute whether the content
* is overflowing.
*/
contentData
:
'<'
,
/** Whether or not truncation should be enabled */
enabled
:
'<?'
,
/**
* Specifies whether controls to expand and collapse
* the excerpt should be shown inside the <excerpt> component.
* If false, external controls can expand/collapse the excerpt by
* setting the 'collapse' property.
*/
inlineControls
:
'<'
,
/** Sets whether or not the excerpt is collapsed. */
collapse
:
'=?'
,
/**
* Called when the collapsibility of the excerpt (that is, whether or
* not the content height exceeds the collapsed height), changes.
*
* Note: This function is *not* called from inside a digest cycle,
* the caller is responsible for triggering any necessary digests.
*/
onCollapsibleChanged
:
'&?'
,
/** The height of this container in pixels when collapsed.
*/
collapsedHeight
:
'<'
,
/**
* The number of pixels by which the height of the excerpt's content
* must extend beyond the collapsed height in order for truncation to
* be activated. This prevents the 'More' link from being shown to expand
* the excerpt if it has only been truncated by a very small amount, such
* that expanding the excerpt would reveal no extra lines of text.
*/
overflowHysteresis
:
'<?'
,
},
transclude
:
true
,
template
:
require
(
'../templates/excerpt.html'
),
};
src/sidebar/
directive
/test/excerpt-test.js
→
src/sidebar/
components
/test/excerpt-test.js
View file @
12d49902
...
...
@@ -2,17 +2,17 @@
var
angular
=
require
(
'angular'
);
var
util
=
require
(
'./util'
);
var
util
=
require
(
'.
./../directive/test
/util'
);
var
excerpt
=
require
(
'../excerpt'
);
describe
(
'excerpt
directive
'
,
function
()
{
describe
(
'excerpt'
,
function
()
{
// ExcerptOverflowMonitor fake instance created by the current test
var
fakeOverflowMonitor
;
var
SHORT_DIV
=
'<div id="foo" style="height:5px;"></div>'
;
var
TALL_DIV
=
'<div id="foo" style="height:200px;">foo bar</div>'
;
function
excerpt
Directive
(
attrs
,
content
)
{
function
excerpt
Component
(
attrs
,
content
)
{
var
defaultAttrs
=
{
enabled
:
true
,
contentData
:
'the content'
,
...
...
@@ -25,7 +25,7 @@ describe('excerpt directive', function () {
before
(
function
()
{
angular
.
module
(
'app'
,
[])
.
directive
(
'excerpt'
,
excerpt
.
directive
);
.
component
(
'excerpt'
,
excerpt
);
});
beforeEach
(
function
()
{
...
...
@@ -45,7 +45,7 @@ describe('excerpt directive', function () {
context
(
'when created'
,
function
()
{
it
(
'schedules an overflow state recalculation'
,
function
()
{
excerpt
Directive
({},
'<span id="foo"></span>'
);
excerpt
Component
({},
'<span id="foo"></span>'
);
assert
.
called
(
fakeOverflowMonitor
.
check
);
});
...
...
@@ -57,7 +57,7 @@ describe('excerpt directive', function () {
inlineControls
:
false
,
overflowHysteresis
:
20
,
};
excerpt
Directive
(
attrs
,
'<span></span>'
);
excerpt
Component
(
attrs
,
'<span></span>'
);
assert
.
deepEqual
(
fakeOverflowMonitor
.
ctrl
.
getState
(),
{
animate
:
attrs
.
animate
,
enabled
:
attrs
.
enabled
,
...
...
@@ -68,14 +68,14 @@ describe('excerpt directive', function () {
});
it
(
'reports the content height to ExcerptOverflowMonitor'
,
function
()
{
excerpt
Directive
({},
TALL_DIV
);
excerpt
Component
({},
TALL_DIV
);
assert
.
deepEqual
(
fakeOverflowMonitor
.
ctrl
.
contentHeight
(),
200
);
});
});
context
(
'input changes'
,
function
()
{
it
(
'schedules an overflow state check when inputs change'
,
function
()
{
var
element
=
excerpt
Directive
({},
'<span></span>'
);
var
element
=
excerpt
Component
({},
'<span></span>'
);
fakeOverflowMonitor
.
check
.
reset
();
element
.
scope
.
contentData
=
'new-content'
;
element
.
scope
.
$digest
();
...
...
@@ -83,7 +83,7 @@ describe('excerpt directive', function () {
});
it
(
'does not schedule a state check if inputs are unchanged'
,
function
()
{
var
element
=
excerpt
Directive
({},
'<span></span>'
);
var
element
=
excerpt
Component
({},
'<span></span>'
);
fakeOverflowMonitor
.
check
.
reset
();
element
.
scope
.
$digest
();
assert
.
notCalled
(
fakeOverflowMonitor
.
check
);
...
...
@@ -92,14 +92,14 @@ describe('excerpt directive', function () {
context
(
'document events'
,
function
()
{
it
(
'schedules an overflow check when media loads'
,
function
()
{
var
element
=
excerpt
Directive
({},
'<img src="https://example.com/foo.jpg">'
);
var
element
=
excerpt
Component
({},
'<img src="https://example.com/foo.jpg">'
);
fakeOverflowMonitor
.
check
.
reset
();
util
.
sendEvent
(
element
[
0
],
'load'
);
assert
.
called
(
fakeOverflowMonitor
.
check
);
});
it
(
'schedules an overflow check when the window is resized'
,
function
()
{
var
element
=
excerpt
Directive
({},
'<span></span>'
);
var
element
=
excerpt
Component
({},
'<span></span>'
);
fakeOverflowMonitor
.
check
.
reset
();
util
.
sendEvent
(
element
[
0
].
ownerDocument
.
defaultView
,
'resize'
);
assert
.
called
(
fakeOverflowMonitor
.
check
);
...
...
@@ -108,7 +108,7 @@ describe('excerpt directive', function () {
context
(
'visibility changes'
,
function
()
{
it
(
'schedules an overflow check when shown'
,
function
()
{
var
element
=
excerpt
Directive
({},
'<span></span>'
);
var
element
=
excerpt
Component
({},
'<span></span>'
);
fakeOverflowMonitor
.
check
.
reset
();
// ng-hide is the class used by the ngShow and ngHide directives
...
...
@@ -126,7 +126,7 @@ describe('excerpt directive', function () {
context
(
'excerpt content style'
,
function
()
{
it
(
'sets the content style using ExcerptOverflowMonitor#contentStyle()'
,
function
()
{
var
element
=
excerpt
Directive
({},
'<span></span>'
);
var
element
=
excerpt
Component
({},
'<span></span>'
);
fakeOverflowMonitor
.
contentStyle
.
returns
({
'max-height'
:
'52px'
});
element
.
scope
.
$digest
();
var
content
=
element
[
0
].
querySelector
(
'.excerpt'
);
...
...
@@ -136,19 +136,19 @@ describe('excerpt directive', function () {
describe
(
'enabled state'
,
function
()
{
it
(
'renders its contents in a .excerpt element by default'
,
function
()
{
var
element
=
excerpt
Directive
({},
'<span id="foo"></span>'
);
var
element
=
excerpt
Component
({},
'<span id="foo"></span>'
);
assert
.
equal
(
element
.
find
(
'.excerpt #foo'
).
length
,
1
);
});
it
(
'when enabled, renders its contents in a .excerpt element'
,
function
()
{
var
element
=
excerpt
Directive
({
enabled
:
true
},
'<span id="foo"></span>'
);
var
element
=
excerpt
Component
({
enabled
:
true
},
'<span id="foo"></span>'
);
assert
.
equal
(
element
.
find
(
'.excerpt #foo'
).
length
,
1
);
});
it
(
'when disabled, renders its contents but not in a .excerpt element'
,
function
()
{
var
element
=
excerpt
Directive
({
enabled
:
false
},
'<span id="foo"></span>'
);
var
element
=
excerpt
Component
({
enabled
:
false
},
'<span id="foo"></span>'
);
assert
.
equal
(
element
.
find
(
'.excerpt #foo'
).
length
,
0
);
assert
.
equal
(
element
.
find
(
'#foo'
).
length
,
1
);
...
...
@@ -175,7 +175,7 @@ describe('excerpt directive', function () {
}
it
(
'displays inline controls if collapsed'
,
function
()
{
var
element
=
excerpt
Directive
({
inlineControls
:
true
},
var
element
=
excerpt
Component
({
inlineControls
:
true
},
TALL_DIV
);
fakeOverflowMonitor
.
ctrl
.
onOverflowChanged
(
true
);
var
expandLink
=
findInlineControl
(
element
[
0
]);
...
...
@@ -184,13 +184,13 @@ describe('excerpt directive', function () {
});
it
(
'does not display inline controls if not collapsed'
,
function
()
{
var
element
=
excerpt
Directive
({
inlineControls
:
true
},
SHORT_DIV
);
var
element
=
excerpt
Component
({
inlineControls
:
true
},
SHORT_DIV
);
var
expandLink
=
findInlineControl
(
element
[
0
]);
assert
.
notOk
(
expandLink
);
});
it
(
'toggles the expanded state when clicked'
,
function
()
{
var
element
=
excerpt
Directive
({
inlineControls
:
true
},
TALL_DIV
);
var
element
=
excerpt
Component
({
inlineControls
:
true
},
TALL_DIV
);
fakeOverflowMonitor
.
ctrl
.
onOverflowChanged
(
true
);
var
expandLink
=
findInlineControl
(
element
[
0
]);
angular
.
element
(
expandLink
.
querySelector
(
'a'
)).
click
();
...
...
@@ -202,7 +202,7 @@ describe('excerpt directive', function () {
describe
(
'bottom area'
,
function
()
{
it
(
'expands the excerpt when clicking at the bottom if collapsed'
,
function
()
{
var
element
=
excerpt
Directive
({
inlineControls
:
true
},
var
element
=
excerpt
Component
({
inlineControls
:
true
},
TALL_DIV
);
element
.
scope
.
$digest
();
assert
.
isTrue
(
element
.
ctrl
.
collapse
);
...
...
@@ -215,7 +215,7 @@ describe('excerpt directive', function () {
describe
(
'#onCollapsibleChanged'
,
function
()
{
it
(
'is called when overflow state changes'
,
function
()
{
var
callback
=
sinon
.
stub
();
excerpt
Directive
({
excerpt
Component
({
onCollapsibleChanged
:
{
args
:
[
'collapsible'
],
callback
:
callback
,
...
...
src/sidebar/directive/excerpt.js
deleted
100644 → 0
View file @
ce2509ba
'use strict'
;
function
ExcerptController
()
{
if
(
this
.
collapse
===
undefined
)
{
this
.
collapse
=
true
;
}
if
(
this
.
animate
===
undefined
)
{
this
.
animate
=
true
;
}
if
(
this
.
enabled
===
undefined
)
{
this
.
enabled
=
true
;
}
this
.
isExpandable
=
function
()
{
return
this
.
overflowing
&&
this
.
collapse
;
};
this
.
isCollapsible
=
function
()
{
return
this
.
overflowing
&&
!
this
.
collapse
;
};
this
.
toggle
=
function
(
event
)
{
// When the user clicks a link explicitly to toggle the collapsed state,
// the event is not propagated.
event
.
stopPropagation
();
this
.
collapse
=
!
this
.
collapse
;
};
this
.
expand
=
function
()
{
// When the user expands the excerpt 'implicitly' by clicking at the bottom
// of the collapsed excerpt, the event is allowed to propagate. For
// annotation cards, this causes clicking on a quote to scroll the view to
// the selected annotation.
this
.
collapse
=
false
;
};
this
.
showInlineControls
=
function
()
{
return
this
.
overflowing
&&
this
.
inlineControls
;
};
this
.
bottomShadowStyles
=
function
()
{
return
{
'excerpt__shadow'
:
true
,
'excerpt__shadow--transparent'
:
this
.
inlineControls
,
'is-hidden'
:
!
this
.
isExpandable
(),
};
};
}
/**
* @ngdoc directive
* @name excerpt
* @restrict E
* @description This directive truncates the height of its contents to a
* specified number of lines and provides controls for expanding
* and collapsing the resulting truncated element.
*/
// @ngInject
function
excerpt
(
ExcerptOverflowMonitor
)
{
return
{
bindToController
:
true
,
controller
:
ExcerptController
,
controllerAs
:
'vm'
,
link
:
function
(
scope
,
elem
,
attrs
,
ctrl
)
{
// Test if the element or any of its parents have been hidden by
// an 'ng-show' directive
function
isElementHidden
()
{
var
el
=
elem
[
0
];
while
(
el
)
{
if
(
el
.
classList
.
contains
(
'ng-hide'
))
{
return
true
;
}
el
=
el
.
parentElement
;
}
return
false
;
}
var
overflowMonitor
=
new
ExcerptOverflowMonitor
({
getState
:
function
()
{
return
{
enabled
:
ctrl
.
enabled
,
animate
:
ctrl
.
animate
,
collapsedHeight
:
ctrl
.
collapsedHeight
,
collapse
:
ctrl
.
collapse
,
overflowHysteresis
:
ctrl
.
overflowHysteresis
,
};
},
contentHeight
:
function
()
{
var
contentElem
=
elem
[
0
].
querySelector
(
'.excerpt'
);
if
(
!
contentElem
)
{
return
null
;
}
return
contentElem
.
scrollHeight
;
},
onOverflowChanged
:
function
(
overflowing
)
{
ctrl
.
overflowing
=
overflowing
;
if
(
ctrl
.
onCollapsibleChanged
)
{
ctrl
.
onCollapsibleChanged
({
collapsible
:
overflowing
});
}
// Even though this change happens outside the framework, we use
// $digest() rather than $apply() here to avoid a large number of full
// digest cycles if many excerpts update their overflow state at the
// same time. The onCollapsibleChanged() handler, if any, is
// responsible for triggering any necessary digests in parent scopes.
scope
.
$digest
();
},
},
window
.
requestAnimationFrame
);
ctrl
.
contentStyle
=
overflowMonitor
.
contentStyle
;
// Listen for document events which might affect whether the excerpt
// is overflowing, even if its content has not changed.
elem
[
0
].
addEventListener
(
'load'
,
overflowMonitor
.
check
,
false
/* capture */
);
window
.
addEventListener
(
'resize'
,
overflowMonitor
.
check
);
scope
.
$on
(
'$destroy'
,
function
()
{
window
.
removeEventListener
(
'resize'
,
overflowMonitor
.
check
);
});
// Watch for changes to the visibility of the excerpt.
// Unfortunately there is no DOM API for this, so we rely on a digest
// being triggered after the visibility changes.
scope
.
$watch
(
isElementHidden
,
function
(
hidden
)
{
if
(
!
hidden
)
{
overflowMonitor
.
check
();
}
});
// Watch input properties which may affect the overflow state
scope
.
$watch
(
'vm.contentData'
,
overflowMonitor
.
check
);
scope
.
$watch
(
'vm.enabled'
,
overflowMonitor
.
check
);
// Trigger an initial calculation of the overflow state.
//
// This is performed asynchronously so that the content of the <excerpt>
// has settled - ie. all Angular directives have been fully applied and
// the DOM has stopped changing. This may take several $digest cycles.
overflowMonitor
.
check
();
},
scope
:
{
/** Whether or not expansion should be animated. Defaults to true. */
animate
:
'<?'
,
/**
* The data which is used to generate the excerpt's content.
* When this changes, the excerpt will recompute whether the content
* is overflowing.
*/
contentData
:
'<'
,
/** Whether or not truncation should be enabled */
enabled
:
'<?'
,
/**
* Specifies whether controls to expand and collapse
* the excerpt should be shown inside the <excerpt> component.
* If false, external controls can expand/collapse the excerpt by
* setting the 'collapse' property.
*/
inlineControls
:
'<'
,
/** Sets whether or not the excerpt is collapsed. */
collapse
:
'=?'
,
/**
* Called when the collapsibility of the excerpt (that is, whether or
* not the content height exceeds the collapsed height), changes.
*
* Note: This function is *not* called from inside a digest cycle,
* the caller is responsible for triggering any necessary digests.
*/
onCollapsibleChanged
:
'&?'
,
/** The height of this container in pixels when collapsed.
*/
collapsedHeight
:
'<'
,
/**
* The number of pixels by which the height of the excerpt's content
* must extend beyond the collapsed height in order for truncation to
* be activated. This prevents the 'More' link from being shown to expand
* the excerpt if it has only been truncated by a very small amount, such
* that expanding the excerpt would reveal no extra lines of text.
*/
overflowHysteresis
:
'<?'
,
},
restrict
:
'E'
,
transclude
:
true
,
template
:
require
(
'../templates/excerpt.html'
),
};
}
module
.
exports
=
{
directive
:
excerpt
,
Controller
:
ExcerptController
,
};
src/sidebar/
directive
/excerpt-overflow-monitor.js
→
src/sidebar/
util
/excerpt-overflow-monitor.js
View file @
12d49902
File moved
src/sidebar/
directive
/test/excerpt-overflow-monitor-test.js
→
src/sidebar/
util
/test/excerpt-overflow-monitor-test.js
View file @
12d49902
File moved
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