Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
20180395
Commit
20180395
authored
Dec 06, 2017
by
Filipa Lacerda
Committed by
Phil Hughes
Dec 06, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Export template selector as ES6 modules
parent
5d9585d1
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
278 additions
and
296 deletions
+278
-296
app/assets/javascripts/commit/image_file.js
app/assets/javascripts/commit/image_file.js
+192
-201
app/assets/javascripts/dispatcher.js
app/assets/javascripts/dispatcher.js
+3
-3
app/assets/javascripts/image_diff/helpers/utils_helper.js
app/assets/javascripts/image_diff/helpers/utils_helper.js
+2
-2
app/assets/javascripts/issue_show/components/fields/description_template.vue
...pts/issue_show/components/fields/description_template.vue
+3
-1
app/assets/javascripts/templates/issuable_template_selector.js
...ssets/javascripts/templates/issuable_template_selector.js
+49
-53
app/assets/javascripts/templates/issuable_template_selectors.js
...sets/javascripts/templates/issuable_template_selectors.js
+23
-26
changelogs/unreleased/38869-templates.yml
changelogs/unreleased/38869-templates.yml
+5
-0
spec/javascripts/image_diff/helpers/utils_helper_spec.js
spec/javascripts/image_diff/helpers/utils_helper_spec.js
+1
-9
spec/javascripts/issue_show/components/form_spec.js
spec/javascripts/issue_show/components/form_spec.js
+0
-1
No files found.
app/assets/javascripts/commit/image_file.js
View file @
20180395
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-use-before-define, prefer-arrow-callback, no-else-return, consistent-return, prefer-template, quotes, one-var, one-var-declaration-per-line, no-unused-vars, no-return-assign, comma-dangle, quote-props, no-unused-expressions, no-sequences, object-shorthand, max-len */
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-use-before-define, prefer-arrow-callback, no-else-return, consistent-return, prefer-template, quotes, one-var, one-var-declaration-per-line, no-unused-vars, no-return-assign, comma-dangle, quote-props, no-unused-expressions, no-sequences, object-shorthand, max-len */
import
'
vendor/jquery.waitforimages
'
;
import
'
vendor/jquery.waitforimages
'
;
(
function
()
{
// Width where images must fits in, for 2-up this gets divided by 2
gl
.
ImageFile
=
(
function
()
{
const
availWidth
=
900
;
var
prepareFrames
;
const
viewModes
=
[
'
two-up
'
,
'
swipe
'
];
// Width where images must fits in, for 2-up this gets divided by 2
export
default
class
ImageFile
{
ImageFile
.
availWidth
=
900
;
constructor
(
file
)
{
this
.
file
=
file
;
ImageFile
.
viewModes
=
[
'
two-up
'
,
'
swipe
'
];
this
.
requestImageInfo
(
$
(
'
.two-up.view .frame.deleted img
'
,
this
.
file
),
(
function
(
_this
)
{
return
function
(
deletedWidth
,
deletedHeight
)
{
function
ImageFile
(
file
)
{
return
_this
.
requestImageInfo
(
$
(
'
.two-up.view .frame.added img
'
,
_this
.
file
),
function
(
width
,
height
)
{
this
.
file
=
file
;
_this
.
initViewModes
();
this
.
requestImageInfo
(
$
(
'
.two-up.view .frame.deleted img
'
,
this
.
file
),
(
function
(
_this
)
{
return
function
(
deletedWidth
,
deletedHeight
)
{
// Load two-up view after images are loaded
return
_this
.
requestImageInfo
(
$
(
'
.two-up.view .frame.added img
'
,
_this
.
file
),
function
(
width
,
height
)
{
// so that we can display the correct width and height information
_this
.
initViewModes
();
const
$images
=
$
(
'
.two-up.view img
'
,
_this
.
file
);
// Load two-up view after images are loaded
$images
.
waitForImages
(
function
()
{
// so that we can display the correct width and height information
_this
.
initView
(
'
two-up
'
);
const
$images
=
$
(
'
.two-up.view img
'
,
_this
.
file
);
});
});
$images
.
waitForImages
(
function
()
{
};
_this
.
initView
(
'
two-up
'
);
})(
this
));
});
}
initViewModes
()
{
const
viewMode
=
viewModes
[
0
];
$
(
'
.view-modes
'
,
this
.
file
).
removeClass
(
'
hide
'
);
$
(
'
.view-modes-menu
'
,
this
.
file
).
on
(
'
click
'
,
'
li
'
,
(
function
(
_this
)
{
return
function
(
event
)
{
if
(
!
$
(
event
.
currentTarget
).
hasClass
(
'
active
'
))
{
return
_this
.
activateViewMode
(
event
.
currentTarget
.
className
);
}
};
})(
this
));
return
this
.
activateViewMode
(
viewMode
);
}
activateViewMode
(
viewMode
)
{
$
(
'
.view-modes-menu li
'
,
this
.
file
).
removeClass
(
'
active
'
).
filter
(
"
.
"
+
viewMode
).
addClass
(
'
active
'
);
return
$
(
"
.view:visible:not(.
"
+
viewMode
+
"
)
"
,
this
.
file
).
fadeOut
(
200
,
(
function
(
_this
)
{
return
function
()
{
$
(
"
.view.
"
+
viewMode
,
_this
.
file
).
fadeIn
(
200
);
return
_this
.
initView
(
viewMode
);
};
})(
this
));
}
initView
(
viewMode
)
{
return
this
.
views
[
viewMode
].
call
(
this
);
}
// eslint-disable-next-line class-methods-use-this
initDraggable
(
$el
,
padding
,
callback
)
{
var
dragging
=
false
;
var
$body
=
$
(
'
body
'
);
var
$offsetEl
=
$el
.
parent
();
$el
.
off
(
'
mousedown
'
).
on
(
'
mousedown
'
,
function
()
{
dragging
=
true
;
$body
.
css
(
'
user-select
'
,
'
none
'
);
});
$body
.
off
(
'
mouseup
'
).
off
(
'
mousemove
'
).
on
(
'
mouseup
'
,
function
()
{
dragging
=
false
;
$body
.
css
(
'
user-select
'
,
''
);
})
.
on
(
'
mousemove
'
,
function
(
e
)
{
var
left
;
if
(
!
dragging
)
return
;
left
=
e
.
pageX
-
(
$offsetEl
.
offset
().
left
+
padding
);
callback
(
e
,
left
);
});
}
prepareFrames
(
view
)
{
var
maxHeight
,
maxWidth
;
maxWidth
=
0
;
maxHeight
=
0
;
$
(
'
.frame
'
,
view
).
each
((
function
(
_this
)
{
return
function
(
index
,
frame
)
{
var
height
,
width
;
width
=
$
(
frame
).
width
();
height
=
$
(
frame
).
height
();
maxWidth
=
width
>
maxWidth
?
width
:
maxWidth
;
return
maxHeight
=
height
>
maxHeight
?
height
:
maxHeight
;
};
})(
this
)).
css
({
width
:
maxWidth
,
height
:
maxHeight
});
return
[
maxWidth
,
maxHeight
];
}
views
=
{
'
two-up
'
:
function
()
{
return
$
(
'
.two-up.view .wrap
'
,
this
.
file
).
each
((
function
(
_this
)
{
return
function
(
index
,
wrap
)
{
$
(
'
img
'
,
wrap
).
each
(
function
()
{
var
currentWidth
;
currentWidth
=
$
(
this
).
width
();
if
(
currentWidth
>
availWidth
/
2
)
{
return
$
(
this
).
width
(
availWidth
/
2
);
}
});
return
_this
.
requestImageInfo
(
$
(
'
img
'
,
wrap
),
function
(
width
,
height
)
{
$
(
'
.image-info .meta-width
'
,
wrap
).
text
(
width
+
"
px
"
);
$
(
'
.image-info .meta-height
'
,
wrap
).
text
(
height
+
"
px
"
);
return
$
(
'
.image-info
'
,
wrap
).
removeClass
(
'
hide
'
);
});
});
};
};
})(
this
));
})(
this
));
}
},
'
swipe
'
:
function
()
{
var
maxHeight
,
maxWidth
;
maxWidth
=
0
;
maxHeight
=
0
;
return
$
(
'
.swipe.view
'
,
this
.
file
).
each
((
function
(
_this
)
{
return
function
(
index
,
view
)
{
var
$swipeWrap
,
$swipeBar
,
$swipeFrame
,
wrapPadding
,
ref
;
ref
=
this
.
prepareFrames
(
view
),
maxWidth
=
ref
[
0
],
maxHeight
=
ref
[
1
];
$swipeFrame
=
$
(
'
.swipe-frame
'
,
view
);
$swipeWrap
=
$
(
'
.swipe-wrap
'
,
view
);
$swipeBar
=
$
(
'
.swipe-bar
'
,
view
);
$swipeFrame
.
css
({
width
:
maxWidth
+
16
,
height
:
maxHeight
+
28
});
$swipeWrap
.
css
({
width
:
maxWidth
+
1
,
height
:
maxHeight
+
2
});
// Set swipeBar left position to match image frame
$swipeBar
.
css
({
left
:
1
});
ImageFile
.
prototype
.
initViewModes
=
function
()
{
wrapPadding
=
parseInt
(
$swipeWrap
.
css
(
'
right
'
).
replace
(
'
px
'
,
''
),
10
);
var
viewMode
;
viewMode
=
ImageFile
.
viewModes
[
0
];
_this
.
initDraggable
(
$swipeBar
,
wrapPadding
,
function
(
e
,
left
)
{
$
(
'
.view-modes
'
,
this
.
file
).
removeClass
(
'
hide
'
);
if
(
left
>
0
&&
left
<
$swipeFrame
.
width
()
-
(
wrapPadding
*
2
))
{
$
(
'
.view-modes-menu
'
,
this
.
file
).
on
(
'
click
'
,
'
li
'
,
(
function
(
_this
)
{
$swipeWrap
.
width
((
maxWidth
+
1
)
-
left
);
return
function
(
event
)
{
$swipeBar
.
css
(
'
left
'
,
left
);
if
(
!
$
(
event
.
currentTarget
).
hasClass
(
'
active
'
))
{
}
return
_this
.
activateViewMode
(
event
.
currentTarget
.
className
);
});
}
};
})(
this
));
return
this
.
activateViewMode
(
viewMode
);
};
ImageFile
.
prototype
.
activateViewMode
=
function
(
viewMode
)
{
$
(
'
.view-modes-menu li
'
,
this
.
file
).
removeClass
(
'
active
'
).
filter
(
"
.
"
+
viewMode
).
addClass
(
'
active
'
);
return
$
(
"
.view:visible:not(.
"
+
viewMode
+
"
)
"
,
this
.
file
).
fadeOut
(
200
,
(
function
(
_this
)
{
return
function
()
{
$
(
"
.view.
"
+
viewMode
,
_this
.
file
).
fadeIn
(
200
);
return
_this
.
initView
(
viewMode
);
};
};
})(
this
));
})(
this
));
};
},
'
onion-skin
'
:
function
()
{
ImageFile
.
prototype
.
initView
=
function
(
viewMode
)
{
var
dragTrackWidth
,
maxHeight
,
maxWidth
;
return
this
.
views
[
viewMode
].
call
(
this
);
maxWidth
=
0
;
};
maxHeight
=
0
;
dragTrackWidth
=
$
(
'
.drag-track
'
,
this
.
file
).
width
()
-
$
(
'
.dragger
'
,
this
.
file
).
width
();
ImageFile
.
prototype
.
initDraggable
=
function
(
$el
,
padding
,
callback
)
{
return
$
(
'
.onion-skin.view
'
,
this
.
file
).
each
((
function
(
_this
)
{
var
dragging
=
false
;
return
function
(
index
,
view
)
{
var
$body
=
$
(
'
body
'
);
var
$frame
,
$track
,
$dragger
,
$frameAdded
,
framePadding
,
ref
,
dragging
=
false
;
var
$offsetEl
=
$el
.
parent
();
ref
=
this
.
prepareFrames
(
view
),
maxWidth
=
ref
[
0
],
maxHeight
=
ref
[
1
];
$frame
=
$
(
'
.onion-skin-frame
'
,
view
);
$el
.
off
(
'
mousedown
'
).
on
(
'
mousedown
'
,
function
()
{
$frameAdded
=
$
(
'
.frame.added
'
,
view
);
dragging
=
true
;
$track
=
$
(
'
.drag-track
'
,
view
);
$body
.
css
(
'
user-select
'
,
'
none
'
);
$dragger
=
$
(
'
.dragger
'
,
$track
);
});
$frame
.
css
({
$body
.
off
(
'
mouseup
'
).
off
(
'
mousemove
'
).
on
(
'
mouseup
'
,
function
()
{
width
:
maxWidth
+
16
,
dragging
=
false
;
height
:
maxHeight
+
28
$body
.
css
(
'
user-select
'
,
''
);
});
})
$
(
'
.swipe-wrap
'
,
view
).
css
({
.
on
(
'
mousemove
'
,
function
(
e
)
{
width
:
maxWidth
+
1
,
var
left
;
height
:
maxHeight
+
2
if
(
!
dragging
)
return
;
});
$dragger
.
css
({
left
:
dragTrackWidth
});
left
=
e
.
pageX
-
(
$offsetEl
.
offset
().
left
+
padding
);
framePadding
=
parseInt
(
$frameAdded
.
css
(
'
right
'
).
replace
(
'
px
'
,
''
),
10
);
callback
(
e
,
left
);
_this
.
initDraggable
(
$dragger
,
framePadding
,
function
(
e
,
left
)
{
});
var
opacity
=
left
/
dragTrackWidth
;
};
prepareFrames
=
function
(
view
)
{
if
(
opacity
>=
0
&&
opacity
<=
1
)
{
var
maxHeight
,
maxWidth
;
$dragger
.
css
(
'
left
'
,
left
);
maxWidth
=
0
;
$frameAdded
.
css
(
'
opacity
'
,
opacity
);
maxHeight
=
0
;
}
$
(
'
.frame
'
,
view
).
each
((
function
(
_this
)
{
});
return
function
(
index
,
frame
)
{
var
height
,
width
;
width
=
$
(
frame
).
width
();
height
=
$
(
frame
).
height
();
maxWidth
=
width
>
maxWidth
?
width
:
maxWidth
;
return
maxHeight
=
height
>
maxHeight
?
height
:
maxHeight
;
};
};
})(
this
)).
css
({
})(
this
));
width
:
maxWidth
,
}
height
:
maxHeight
}
});
return
[
maxWidth
,
maxHeight
];
requestImageInfo
(
img
,
callback
)
{
};
const
domImg
=
img
.
get
(
0
);
if
(
domImg
)
{
ImageFile
.
prototype
.
views
=
{
if
(
domImg
.
complete
)
{
'
two-up
'
:
function
()
{
return
callback
.
call
(
this
,
domImg
.
naturalWidth
,
domImg
.
naturalHeight
);
return
$
(
'
.two-up.view .wrap
'
,
this
.
file
).
each
((
function
(
_this
)
{
}
else
{
return
function
(
index
,
wrap
)
{
return
img
.
on
(
'
load
'
,
(
function
(
_this
)
{
$
(
'
img
'
,
wrap
).
each
(
function
()
{
return
function
()
{
var
currentWidth
;
return
callback
.
call
(
_this
,
domImg
.
naturalWidth
,
domImg
.
naturalHeight
);
currentWidth
=
$
(
this
).
width
();
if
(
currentWidth
>
ImageFile
.
availWidth
/
2
)
{
return
$
(
this
).
width
(
ImageFile
.
availWidth
/
2
);
}
});
return
_this
.
requestImageInfo
(
$
(
'
img
'
,
wrap
),
function
(
width
,
height
)
{
$
(
'
.image-info .meta-width
'
,
wrap
).
text
(
width
+
"
px
"
);
$
(
'
.image-info .meta-height
'
,
wrap
).
text
(
height
+
"
px
"
);
return
$
(
'
.image-info
'
,
wrap
).
removeClass
(
'
hide
'
);
});
};
})(
this
));
},
'
swipe
'
:
function
()
{
var
maxHeight
,
maxWidth
;
maxWidth
=
0
;
maxHeight
=
0
;
return
$
(
'
.swipe.view
'
,
this
.
file
).
each
((
function
(
_this
)
{
return
function
(
index
,
view
)
{
var
$swipeWrap
,
$swipeBar
,
$swipeFrame
,
wrapPadding
,
ref
;
ref
=
prepareFrames
(
view
),
maxWidth
=
ref
[
0
],
maxHeight
=
ref
[
1
];
$swipeFrame
=
$
(
'
.swipe-frame
'
,
view
);
$swipeWrap
=
$
(
'
.swipe-wrap
'
,
view
);
$swipeBar
=
$
(
'
.swipe-bar
'
,
view
);
$swipeFrame
.
css
({
width
:
maxWidth
+
16
,
height
:
maxHeight
+
28
});
$swipeWrap
.
css
({
width
:
maxWidth
+
1
,
height
:
maxHeight
+
2
});
// Set swipeBar left position to match image frame
$swipeBar
.
css
({
left
:
1
});
wrapPadding
=
parseInt
(
$swipeWrap
.
css
(
'
right
'
).
replace
(
'
px
'
,
''
),
10
);
_this
.
initDraggable
(
$swipeBar
,
wrapPadding
,
function
(
e
,
left
)
{
if
(
left
>
0
&&
left
<
$swipeFrame
.
width
()
-
(
wrapPadding
*
2
))
{
$swipeWrap
.
width
((
maxWidth
+
1
)
-
left
);
$swipeBar
.
css
(
'
left
'
,
left
);
}
});
};
})(
this
));
},
'
onion-skin
'
:
function
()
{
var
dragTrackWidth
,
maxHeight
,
maxWidth
;
maxWidth
=
0
;
maxHeight
=
0
;
dragTrackWidth
=
$
(
'
.drag-track
'
,
this
.
file
).
width
()
-
$
(
'
.dragger
'
,
this
.
file
).
width
();
return
$
(
'
.onion-skin.view
'
,
this
.
file
).
each
((
function
(
_this
)
{
return
function
(
index
,
view
)
{
var
$frame
,
$track
,
$dragger
,
$frameAdded
,
framePadding
,
ref
,
dragging
=
false
;
ref
=
prepareFrames
(
view
),
maxWidth
=
ref
[
0
],
maxHeight
=
ref
[
1
];
$frame
=
$
(
'
.onion-skin-frame
'
,
view
);
$frameAdded
=
$
(
'
.frame.added
'
,
view
);
$track
=
$
(
'
.drag-track
'
,
view
);
$dragger
=
$
(
'
.dragger
'
,
$track
);
$frame
.
css
({
width
:
maxWidth
+
16
,
height
:
maxHeight
+
28
});
$
(
'
.swipe-wrap
'
,
view
).
css
({
width
:
maxWidth
+
1
,
height
:
maxHeight
+
2
});
$dragger
.
css
({
left
:
dragTrackWidth
});
framePadding
=
parseInt
(
$frameAdded
.
css
(
'
right
'
).
replace
(
'
px
'
,
''
),
10
);
_this
.
initDraggable
(
$dragger
,
framePadding
,
function
(
e
,
left
)
{
var
opacity
=
left
/
dragTrackWidth
;
if
(
opacity
>=
0
&&
opacity
<=
1
)
{
$dragger
.
css
(
'
left
'
,
left
);
$frameAdded
.
css
(
'
opacity
'
,
opacity
);
}
});
};
};
})(
this
));
})(
this
));
}
}
};
}
}
ImageFile
.
prototype
.
requestImageInfo
=
function
(
img
,
callback
)
{
}
var
domImg
;
domImg
=
img
.
get
(
0
);
if
(
domImg
)
{
if
(
domImg
.
complete
)
{
return
callback
.
call
(
this
,
domImg
.
naturalWidth
,
domImg
.
naturalHeight
);
}
else
{
return
img
.
on
(
'
load
'
,
(
function
(
_this
)
{
return
function
()
{
return
callback
.
call
(
_this
,
domImg
.
naturalWidth
,
domImg
.
naturalHeight
);
};
})(
this
));
}
}
};
return
ImageFile
;
})();
}).
call
(
window
);
app/assets/javascripts/dispatcher.js
View file @
20180395
...
@@ -30,7 +30,7 @@ import projectImport from './project_import';
...
@@ -30,7 +30,7 @@ import projectImport from './project_import';
import
Labels
from
'
./labels
'
;
import
Labels
from
'
./labels
'
;
import
LabelManager
from
'
./label_manager
'
;
import
LabelManager
from
'
./label_manager
'
;
/* global Sidebar */
/* global Sidebar */
import
IssuableTemplateSelectors
from
'
./templates/issuable_template_selectors
'
;
import
Flash
from
'
./flash
'
;
import
Flash
from
'
./flash
'
;
import
CommitsList
from
'
./commits
'
;
import
CommitsList
from
'
./commits
'
;
import
Issue
from
'
./issue
'
;
import
Issue
from
'
./issue
'
;
...
@@ -264,7 +264,7 @@ import ProjectVariables from './project_variables';
...
@@ -264,7 +264,7 @@ import ProjectVariables from './project_variables';
new
IssuableForm
(
$
(
'
.issue-form
'
));
new
IssuableForm
(
$
(
'
.issue-form
'
));
new
LabelsSelect
();
new
LabelsSelect
();
new
MilestoneSelect
();
new
MilestoneSelect
();
new
gl
.
IssuableTemplateSelectors
();
new
IssuableTemplateSelectors
();
break
;
break
;
case
'
projects:merge_requests:creations:new
'
:
case
'
projects:merge_requests:creations:new
'
:
const
mrNewCompareNode
=
document
.
querySelector
(
'
.js-merge-request-new-compare
'
);
const
mrNewCompareNode
=
document
.
querySelector
(
'
.js-merge-request-new-compare
'
);
...
@@ -288,7 +288,7 @@ import ProjectVariables from './project_variables';
...
@@ -288,7 +288,7 @@ import ProjectVariables from './project_variables';
new
IssuableForm
(
$
(
'
.merge-request-form
'
));
new
IssuableForm
(
$
(
'
.merge-request-form
'
));
new
LabelsSelect
();
new
LabelsSelect
();
new
MilestoneSelect
();
new
MilestoneSelect
();
new
gl
.
IssuableTemplateSelectors
();
new
IssuableTemplateSelectors
();
new
AutoWidthDropdownSelect
(
$
(
'
.js-target-branch-select
'
)).
init
();
new
AutoWidthDropdownSelect
(
$
(
'
.js-target-branch-select
'
)).
init
();
break
;
break
;
case
'
projects:tags:new
'
:
case
'
projects:tags:new
'
:
...
...
app/assets/javascripts/image_diff/helpers/utils_helper.js
View file @
20180395
import
ImageBadge
from
'
../image_badge
'
;
import
ImageBadge
from
'
../image_badge
'
;
import
ImageDiff
from
'
../image_diff
'
;
import
ImageDiff
from
'
../image_diff
'
;
import
ReplacedImageDiff
from
'
../replaced_image_diff
'
;
import
ReplacedImageDiff
from
'
../replaced_image_diff
'
;
import
'
../../commit/image_file
'
;
import
ImageFile
from
'
../../commit/image_file
'
;
export
function
resizeCoordinatesToImageElement
(
imageEl
,
meta
)
{
export
function
resizeCoordinatesToImageElement
(
imageEl
,
meta
)
{
const
{
x
,
y
,
width
,
height
}
=
meta
;
const
{
x
,
y
,
width
,
height
}
=
meta
;
...
@@ -81,7 +81,7 @@ export function initImageDiff(fileEl, canCreateNote, renderCommentBadge) {
...
@@ -81,7 +81,7 @@ export function initImageDiff(fileEl, canCreateNote, renderCommentBadge) {
// ImageFile needs to be invoked before initImageDiff so that badges
// ImageFile needs to be invoked before initImageDiff so that badges
// can mount to the correct location
// can mount to the correct location
new
gl
.
ImageFile
(
fileEl
);
// eslint-disable-line no-new
new
ImageFile
(
fileEl
);
// eslint-disable-line no-new
if
(
fileEl
.
querySelector
(
'
.diff-file .js-single-image
'
))
{
if
(
fileEl
.
querySelector
(
'
.diff-file .js-single-image
'
))
{
diff
=
new
ImageDiff
(
fileEl
,
options
);
diff
=
new
ImageDiff
(
fileEl
,
options
);
...
...
app/assets/javascripts/issue_show/components/fields/description_template.vue
View file @
20180395
<
script
>
<
script
>
import
IssuableTemplateSelectors
from
'
../../../templates/issuable_template_selectors
'
;
export
default
{
export
default
{
props
:
{
props
:
{
formState
:
{
formState
:
{
...
@@ -32,7 +34,7 @@
...
@@ -32,7 +34,7 @@
};
};
editor
.
getValue
=
()
=>
this
.
formState
.
description
;
editor
.
getValue
=
()
=>
this
.
formState
.
description
;
this
.
issuableTemplate
=
new
gl
.
IssuableTemplateSelectors
({
this
.
issuableTemplate
=
new
IssuableTemplateSelectors
({
$dropdowns
:
$
(
this
.
$refs
.
toggle
),
$dropdowns
:
$
(
this
.
$refs
.
toggle
),
editor
,
editor
,
});
});
...
...
app/assets/javascripts/templates/issuable_template_selector.js
View file @
20180395
/* eslint-disable comma-dangle, max-len, no-useless-return, no-param-reassign, max-len */
/* eslint-disable no-useless-return, max-len */
import
Api
from
'
../api
'
;
import
Api
from
'
../api
'
;
import
TemplateSelector
from
'
../blob/template_selector
'
;
import
TemplateSelector
from
'
../blob/template_selector
'
;
((
global
)
=>
{
export
default
class
IssuableTemplateSelector
extends
TemplateSelector
{
class
IssuableTemplateSelector
extends
TemplateSelector
{
constructor
(...
args
)
{
constructor
(...
args
)
{
super
(...
args
);
super
(...
args
);
this
.
projectPath
=
this
.
dropdown
.
data
(
'
project-path
'
);
this
.
projectPath
=
this
.
dropdown
.
data
(
'
project-path
'
);
this
.
namespacePath
=
this
.
dropdown
.
data
(
'
namespace-path
'
);
this
.
namespacePath
=
this
.
dropdown
.
data
(
'
namespace-path
'
);
this
.
issuableType
=
this
.
$dropdownContainer
.
data
(
'
issuable-type
'
);
this
.
issuableType
=
this
.
$dropdownContainer
.
data
(
'
issuable-type
'
);
this
.
titleInput
=
$
(
`#
${
this
.
issuableType
}
_title`
);
this
.
titleInput
=
$
(
`#
${
this
.
issuableType
}
_title`
);
const
initialQuery
=
{
const
initialQuery
=
{
name
:
this
.
dropdown
.
data
(
'
selected
'
),
name
:
this
.
dropdown
.
data
(
'
selected
'
)
};
};
if
(
initialQuery
.
name
)
this
.
requestFile
(
initialQuery
);
if
(
initialQuery
.
name
)
this
.
requestFile
(
initialQuery
);
$
(
'
.reset-template
'
,
this
.
dropdown
.
parent
()).
on
(
'
click
'
,
()
=>
{
$
(
'
.reset-template
'
,
this
.
dropdown
.
parent
()).
on
(
'
click
'
,
()
=>
{
this
.
setInputValueToTemplateContent
();
this
.
setInputValueToTemplateContent
();
});
});
$
(
'
.no-template
'
,
this
.
dropdown
.
parent
()).
on
(
'
click
'
,
()
=>
{
$
(
'
.no-template
'
,
this
.
dropdown
.
parent
()).
on
(
'
click
'
,
()
=>
{
this
.
currentTemplate
.
content
=
''
;
this
.
currentTemplate
.
content
=
''
;
this
.
setInputValueToTemplateContent
();
this
.
setInputValueToTemplateContent
();
$
(
'
.dropdown-toggle-text
'
,
this
.
dropdown
).
text
(
'
Choose a template
'
);
$
(
'
.dropdown-toggle-text
'
,
this
.
dropdown
).
text
(
'
Choose a template
'
);
});
});
}
}
requestFile
(
query
)
{
requestFile
(
query
)
{
this
.
startLoadingSpinner
();
this
.
startLoadingSpinner
();
Api
.
issueTemplate
(
this
.
namespacePath
,
this
.
projectPath
,
query
.
name
,
this
.
issuableType
,
(
err
,
currentTemplate
)
=>
{
Api
.
issueTemplate
(
this
.
namespacePath
,
this
.
projectPath
,
query
.
name
,
this
.
issuableType
,
(
err
,
currentTemplate
)
=>
{
this
.
currentTemplate
=
currentTemplate
;
this
.
currentTemplate
=
currentTemplate
;
if
(
err
)
return
;
// Error handled by global AJAX error handler
if
(
err
)
return
;
// Error handled by global AJAX error handler
this
.
stopLoadingSpinner
();
this
.
stopLoadingSpinner
();
this
.
setInputValueToTemplateContent
();
this
.
setInputValueToTemplateContent
();
});
});
return
;
return
;
}
}
setInputValueToTemplateContent
()
{
setInputValueToTemplateContent
()
{
// `this.setEditorContent` sets the value of the description input field
// `this.setEditorContent` sets the value of the description input field
// to the content of the template selected.
// to the content of the template selected.
if
(
this
.
titleInput
.
val
()
===
''
)
{
if
(
this
.
titleInput
.
val
()
===
''
)
{
// If the title has not yet been set, focus the title input and
// If the title has not yet been set, focus the title input and
// skip focusing the description input by setting `true` as the
// skip focusing the description input by setting `true` as the
// `skipFocus` option to `setEditorContent`.
// `skipFocus` option to `setEditorContent`.
this
.
setEditorContent
(
this
.
currentTemplate
,
{
skipFocus
:
true
});
this
.
setEditorContent
(
this
.
currentTemplate
,
{
skipFocus
:
true
});
this
.
titleInput
.
focus
();
this
.
titleInput
.
focus
();
}
else
{
}
else
{
this
.
setEditorContent
(
this
.
currentTemplate
,
{
skipFocus
:
false
});
this
.
setEditorContent
(
this
.
currentTemplate
,
{
skipFocus
:
false
});
}
return
;
}
}
return
;
}
}
}
global
.
IssuableTemplateSelector
=
IssuableTemplateSelector
;
})(
window
.
gl
||
(
window
.
gl
=
{}));
app/assets/javascripts/templates/issuable_template_selectors.js
View file @
20180395
/* eslint-disable no-new, comma-dangle, class-methods-use-this, no-param-reassign */
/* eslint-disable no-new, class-methods-use-this */
import
IssuableTemplateSelector
from
'
./issuable_template_selector
'
;
((
global
)
=>
{
export
default
class
IssuableTemplateSelectors
{
class
IssuableTemplateSelectors
{
constructor
({
$dropdowns
,
editor
}
=
{})
{
constructor
({
$dropdowns
,
editor
}
=
{})
{
this
.
$dropdowns
=
$dropdowns
||
$
(
'
.js-issuable-selector
'
);
this
.
$dropdowns
=
$dropdowns
||
$
(
'
.js-issuable-selector
'
);
this
.
editor
=
editor
||
this
.
initEditor
();
this
.
editor
=
editor
||
this
.
initEditor
();
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
const
$dropdown
=
$
(
dropdown
);
const
$dropdown
=
$
(
dropdown
);
new
gl
.
IssuableTemplateSelector
({
new
IssuableTemplateSelector
({
pattern
:
/
(\.
md
)
/
,
pattern
:
/
(\.
md
)
/
,
data
:
$dropdown
.
data
(
'
data
'
),
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-issuable-selector-wrap
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-issuable-selector-wrap
'
),
dropdown
:
$dropdown
,
dropdown
:
$dropdown
,
editor
:
this
.
editor
editor
:
this
.
editor
,
});
});
});
}
});
initEditor
()
{
const
editor
=
$
(
'
.markdown-area
'
);
// Proxy ace-editor's .setValue to jQuery's .val
editor
.
setValue
=
editor
.
val
;
editor
.
getValue
=
editor
.
val
;
return
editor
;
}
}
}
global
.
IssuableTemplateSelectors
=
IssuableTemplateSelectors
;
initEditor
()
{
})(
window
.
gl
||
(
window
.
gl
=
{}));
const
editor
=
$
(
'
.markdown-area
'
);
// Proxy ace-editor's .setValue to jQuery's .val
editor
.
setValue
=
editor
.
val
;
editor
.
getValue
=
editor
.
val
;
return
editor
;
}
}
changelogs/unreleased/38869-templates.yml
0 → 100644
View file @
20180395
---
title
:
Remove template selector from global namespace
merge_request
:
author
:
type
:
performance
spec/javascripts/image_diff/helpers/utils_helper_spec.js
View file @
20180395
...
@@ -157,27 +157,19 @@ describe('utilsHelper', () => {
...
@@ -157,27 +157,19 @@ describe('utilsHelper', () => {
beforeEach
(()
=>
{
beforeEach
(()
=>
{
window
.
gl
=
window
.
gl
||
(
window
.
gl
=
{});
window
.
gl
=
window
.
gl
||
(
window
.
gl
=
{});
glCache
=
window
.
gl
;
glCache
=
window
.
gl
;
window
.
gl
.
ImageFile
=
()
=>
{};
fileEl
=
document
.
createElement
(
'
div
'
);
fileEl
=
document
.
createElement
(
'
div
'
);
fileEl
.
innerHTML
=
`
fileEl
.
innerHTML
=
`
<div class="diff-file"></div>
<div class="diff-file"></div>
`
;
`
;
spyOn
(
ImageDiff
.
prototype
,
'
init
'
).
and
.
callFake
(()
=>
{});
spyOn
(
ReplacedImageDiff
.
prototype
,
'
init
'
).
and
.
callFake
(()
=>
{});
spyOn
(
ReplacedImageDiff
.
prototype
,
'
init
'
).
and
.
callFake
(()
=>
{});
spyOn
(
ImageDiff
.
prototype
,
'
init
'
).
and
.
callFake
(()
=>
{});
});
});
afterEach
(()
=>
{
afterEach
(()
=>
{
window
.
gl
=
glCache
;
window
.
gl
=
glCache
;
});
});
it
(
'
should initialize gl.ImageFile
'
,
()
=>
{
spyOn
(
window
.
gl
,
'
ImageFile
'
);
utilsHelper
.
initImageDiff
(
fileEl
,
false
,
false
);
expect
(
gl
.
ImageFile
).
toHaveBeenCalled
();
});
it
(
'
should initialize ImageDiff if js-single-image
'
,
()
=>
{
it
(
'
should initialize ImageDiff if js-single-image
'
,
()
=>
{
const
diffFileEl
=
fileEl
.
querySelector
(
'
.diff-file
'
);
const
diffFileEl
=
fileEl
.
querySelector
(
'
.diff-file
'
);
diffFileEl
.
innerHTML
=
`
diffFileEl
.
innerHTML
=
`
...
...
spec/javascripts/issue_show/components/form_spec.js
View file @
20180395
...
@@ -34,7 +34,6 @@ describe('Inline edit form component', () => {
...
@@ -34,7 +34,6 @@ describe('Inline edit form component', () => {
});
});
it
(
'
renders template selector when templates exists
'
,
(
done
)
=>
{
it
(
'
renders template selector when templates exists
'
,
(
done
)
=>
{
spyOn
(
gl
,
'
IssuableTemplateSelectors
'
);
vm
.
issuableTemplates
=
[
'
test
'
];
vm
.
issuableTemplates
=
[
'
test
'
];
Vue
.
nextTick
(()
=>
{
Vue
.
nextTick
(()
=>
{
...
...
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