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
1
Merge Requests
1
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
nexedi
gitlab-ce
Commits
c7132929
Commit
c7132929
authored
Apr 05, 2017
by
Jacob Schatz
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'sketch-preview-files' into 'master'
Load a preview of Sketch 43 files See merge request !10470
parents
5771ee40
fd8a4078
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
293 additions
and
2 deletions
+293
-2
app/assets/javascripts/blob/sketch/index.js
app/assets/javascripts/blob/sketch/index.js
+73
-0
app/assets/javascripts/blob/sketch_viewer.js
app/assets/javascripts/blob/sketch_viewer.js
+8
-0
app/models/blob.rb
app/models/blob.rb
+6
-0
app/views/projects/blob/_sketch.html.haml
app/views/projects/blob/_sketch.html.haml
+7
-0
config/dependency_decisions.yml
config/dependency_decisions.yml
+18
-0
config/webpack.config.js
config/webpack.config.js
+1
-0
package.json
package.json
+2
-0
spec/javascripts/blob/sketch/index_spec.js
spec/javascripts/blob/sketch/index_spec.js
+118
-0
spec/javascripts/fixtures/sketch_viewer.html.haml
spec/javascripts/fixtures/sketch_viewer.html.haml
+2
-0
spec/models/blob_spec.rb
spec/models/blob_spec.rb
+21
-1
yarn.lock
yarn.lock
+37
-1
No files found.
app/assets/javascripts/blob/sketch/index.js
0 → 100644
View file @
c7132929
import
JSZip
from
'
jszip
'
;
import
JSZipUtils
from
'
jszip-utils
'
;
export
default
class
SketchLoader
{
constructor
(
container
)
{
this
.
container
=
container
;
this
.
loadingIcon
=
this
.
container
.
querySelector
(
'
.js-loading-icon
'
);
this
.
load
();
}
load
()
{
return
this
.
getZipFile
()
.
then
(
data
=>
JSZip
.
loadAsync
(
data
))
.
then
(
asyncResult
=>
asyncResult
.
files
[
'
previews/preview.png
'
].
async
(
'
uint8array
'
))
.
then
((
content
)
=>
{
const
url
=
window
.
URL
||
window
.
webkitURL
;
const
blob
=
new
Blob
([
new
Uint8Array
(
content
)],
{
type
:
'
image/png
'
,
});
const
previewUrl
=
url
.
createObjectURL
(
blob
);
this
.
render
(
previewUrl
);
})
.
catch
(
this
.
error
.
bind
(
this
));
}
getZipFile
()
{
return
new
JSZip
.
external
.
Promise
((
resolve
,
reject
)
=>
{
JSZipUtils
.
getBinaryContent
(
this
.
container
.
dataset
.
endpoint
,
(
err
,
data
)
=>
{
if
(
err
)
{
reject
(
err
);
}
else
{
resolve
(
data
);
}
});
});
}
render
(
previewUrl
)
{
const
previewLink
=
document
.
createElement
(
'
a
'
);
const
previewImage
=
document
.
createElement
(
'
img
'
);
previewLink
.
href
=
previewUrl
;
previewLink
.
target
=
'
_blank
'
;
previewImage
.
src
=
previewUrl
;
previewImage
.
className
=
'
img-responsive
'
;
previewLink
.
appendChild
(
previewImage
);
this
.
container
.
appendChild
(
previewLink
);
this
.
removeLoadingIcon
();
}
error
()
{
const
errorMsg
=
document
.
createElement
(
'
p
'
);
errorMsg
.
className
=
'
prepend-top-default append-bottom-default text-center
'
;
errorMsg
.
textContent
=
`
Cannot show preview. For previews on sketch files, they must have the file format
introduced by Sketch version 43 and above.
`
;
this
.
container
.
appendChild
(
errorMsg
);
this
.
removeLoadingIcon
();
}
removeLoadingIcon
()
{
if
(
this
.
loadingIcon
)
{
this
.
loadingIcon
.
remove
();
}
}
}
app/assets/javascripts/blob/sketch_viewer.js
0 → 100644
View file @
c7132929
/* eslint-disable no-new */
import
SketchLoader
from
'
./sketch
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
el
=
document
.
getElementById
(
'
js-sketch-viewer
'
);
new
SketchLoader
(
el
);
});
app/models/blob.rb
View file @
c7132929
...
...
@@ -50,6 +50,10 @@ class Blob < SimpleDelegator
text?
&&
language
&
.
name
==
'Jupyter Notebook'
end
def
sketch?
binary?
&&
extname
.
downcase
.
delete
(
'.'
)
==
'sketch'
end
def
size_within_svg_limits?
size
<=
MAXIMUM_SVG_SIZE
end
...
...
@@ -69,6 +73,8 @@ class Blob < SimpleDelegator
'image'
elsif
ipython_notebook?
'notebook'
elsif
sketch?
'sketch'
elsif
text?
'text'
else
...
...
app/views/projects/blob/_sketch.html.haml
0 → 100644
View file @
c7132929
-
content_for
:page_specific_javascripts
do
=
page_specific_javascript_bundle_tag
(
'common_vue'
)
=
page_specific_javascript_bundle_tag
(
'sketch_viewer'
)
.file-content
#js-sketch-viewer
{
data:
{
endpoint:
namespace_project_raw_path
(
@project
.
namespace
,
@project
,
@id
)
}
}
.js-loading-icon.text-center.prepend-top-default.append-bottom-default.js-loading-icon
{
'aria-label'
=>
'Loading Sketch preview'
}
=
icon
(
'spinner spin 2x'
,
'aria-hidden'
=>
'true'
);
config/dependency_decisions.yml
View file @
c7132929
...
...
@@ -326,3 +326,21 @@
:why: https://github.com/domenic/opener/blob/1.4.3/LICENSE.txt
:versions: []
:when: 2017-02-21 22:33:41.729629000 Z
-
-
:approve
-
jszip
-
:who: Phil Hughes
:why: https://github.com/Stuk/jszip/blob/master/LICENSE.markdown
:versions: []
:when: 2017-04-05 10:38:46.275721000 Z
-
-
:approve
-
jszip-utils
-
:who: Phil Hughes
:why: https://github.com/Stuk/jszip-utils/blob/master/LICENSE.markdown
:versions: []
:when: 2017-04-05 10:39:32.676232000 Z
-
-
:approve
-
pako
-
:who: Phil Hughes
:why: https://github.com/nodeca/pako/blob/master/LICENSE
:versions: []
:when: 2017-04-05 10:43:45.897720000 Z
config/webpack.config.js
View file @
c7132929
...
...
@@ -37,6 +37,7 @@ var config = {
monitoring
:
'
./monitoring/monitoring_bundle.js
'
,
network
:
'
./network/network_bundle.js
'
,
notebook_viewer
:
'
./blob/notebook_viewer.js
'
,
sketch_viewer
:
'
./blob/sketch_viewer.js
'
,
profile
:
'
./profile/profile_bundle.js
'
,
protected_branches
:
'
./protected_branches/protected_branches_bundle.js
'
,
snippet
:
'
./snippet/snippet_bundle.js
'
,
...
...
package.json
View file @
c7132929
...
...
@@ -27,6 +27,8 @@
"
jquery
"
:
"
^2.2.1
"
,
"
jquery-ujs
"
:
"
^1.2.1
"
,
"
js-cookie
"
:
"
^2.1.3
"
,
"
jszip
"
:
"
^3.1.3
"
,
"
jszip-utils
"
:
"
^0.0.2
"
,
"
mousetrap
"
:
"
^1.4.6
"
,
"
pikaday
"
:
"
^1.5.1
"
,
"
raphael
"
:
"
^2.2.7
"
,
...
...
spec/javascripts/blob/sketch/index_spec.js
0 → 100644
View file @
c7132929
/* eslint-disable no-new */
import
JSZip
from
'
jszip
'
;
import
SketchLoader
from
'
~/blob/sketch
'
;
describe
(
'
Sketch viewer
'
,
()
=>
{
const
generateZipFileArrayBuffer
=
(
zipFile
,
resolve
,
done
)
=>
{
zipFile
.
generateAsync
({
type
:
'
arrayBuffer
'
})
.
then
((
content
)
=>
{
resolve
(
content
);
setTimeout
(()
=>
{
done
();
},
100
);
});
};
preloadFixtures
(
'
static/sketch_viewer.html.raw
'
);
beforeEach
(()
=>
{
loadFixtures
(
'
static/sketch_viewer.html.raw
'
);
});
describe
(
'
with error message
'
,
()
=>
{
beforeEach
((
done
)
=>
{
spyOn
(
SketchLoader
.
prototype
,
'
getZipFile
'
).
and
.
callFake
(()
=>
new
Promise
((
resolve
,
reject
)
=>
{
reject
();
setTimeout
(()
=>
{
done
();
});
}));
new
SketchLoader
(
document
.
getElementById
(
'
js-sketch-viewer
'
));
});
it
(
'
renders error message
'
,
()
=>
{
expect
(
document
.
querySelector
(
'
#js-sketch-viewer p
'
),
).
not
.
toBeNull
();
expect
(
document
.
querySelector
(
'
#js-sketch-viewer p
'
).
textContent
.
trim
(),
).
toContain
(
'
Cannot show preview.
'
);
});
it
(
'
removes render the loading icon
'
,
()
=>
{
expect
(
document
.
querySelector
(
'
.js-loading-icon
'
),
).
toBeNull
();
});
});
describe
(
'
success
'
,
()
=>
{
beforeEach
((
done
)
=>
{
spyOn
(
SketchLoader
.
prototype
,
'
getZipFile
'
).
and
.
callFake
(()
=>
new
Promise
((
resolve
)
=>
{
const
zipFile
=
new
JSZip
();
zipFile
.
folder
(
'
previews
'
)
.
file
(
'
preview.png
'
,
'
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAA1JREFUeNoBAgD9/wAAAAIAAVMrnDAAAAAASUVORK5CYII=
'
,
{
base64
:
true
,
});
generateZipFileArrayBuffer
(
zipFile
,
resolve
,
done
);
}));
new
SketchLoader
(
document
.
getElementById
(
'
js-sketch-viewer
'
));
});
it
(
'
does not render error message
'
,
()
=>
{
expect
(
document
.
querySelector
(
'
#js-sketch-viewer p
'
),
).
toBeNull
();
});
it
(
'
removes render the loading icon
'
,
()
=>
{
expect
(
document
.
querySelector
(
'
.js-loading-icon
'
),
).
toBeNull
();
});
it
(
'
renders preview img
'
,
()
=>
{
const
img
=
document
.
querySelector
(
'
#js-sketch-viewer img
'
);
expect
(
img
).
not
.
toBeNull
();
expect
(
img
.
classList
.
contains
(
'
img-responsive
'
)).
toBeTruthy
();
});
it
(
'
renders link to image
'
,
()
=>
{
const
img
=
document
.
querySelector
(
'
#js-sketch-viewer img
'
);
const
link
=
document
.
querySelector
(
'
#js-sketch-viewer a
'
);
expect
(
link
.
href
).
toBe
(
img
.
src
);
expect
(
link
.
target
).
toBe
(
'
_blank
'
);
});
});
describe
(
'
incorrect file
'
,
()
=>
{
beforeEach
((
done
)
=>
{
spyOn
(
SketchLoader
.
prototype
,
'
getZipFile
'
).
and
.
callFake
(()
=>
new
Promise
((
resolve
)
=>
{
const
zipFile
=
new
JSZip
();
generateZipFileArrayBuffer
(
zipFile
,
resolve
,
done
);
}));
new
SketchLoader
(
document
.
getElementById
(
'
js-sketch-viewer
'
));
});
it
(
'
renders error message
'
,
()
=>
{
expect
(
document
.
querySelector
(
'
#js-sketch-viewer p
'
),
).
not
.
toBeNull
();
expect
(
document
.
querySelector
(
'
#js-sketch-viewer p
'
).
textContent
.
trim
(),
).
toContain
(
'
Cannot show preview.
'
);
});
});
});
spec/javascripts/fixtures/sketch_viewer.html.haml
0 → 100644
View file @
c7132929
.file-content
#js-sketch-viewer
{
data:
{
endpoint:
'/test_sketch_file.sketch'
}
}
.js-loading-icon
spec/models/blob_spec.rb
View file @
c7132929
...
...
@@ -67,6 +67,20 @@ describe Blob do
end
end
describe
'#sketch?'
do
it
'is falsey with image extension'
do
git_blob
=
Gitlab
::
Git
::
Blob
.
new
(
name:
"design.png"
)
expect
(
described_class
.
decorate
(
git_blob
)).
not_to
be_sketch
end
it
'is truthy with sketch extension'
do
git_blob
=
Gitlab
::
Git
::
Blob
.
new
(
name:
"design.sketch"
)
expect
(
described_class
.
decorate
(
git_blob
)).
to
be_sketch
end
end
describe
'#video?'
do
it
'is falsey with image extension'
do
git_blob
=
Gitlab
::
Git
::
Blob
.
new
(
name:
'image.png'
)
...
...
@@ -92,7 +106,8 @@ describe Blob do
language:
nil
,
lfs_pointer?:
false
,
svg?:
false
,
text?:
false
text?:
false
,
binary?:
false
)
described_class
.
decorate
(
double
).
tap
do
|
blob
|
...
...
@@ -135,6 +150,11 @@ describe Blob do
blob
=
stubbed_blob
(
text?:
true
,
ipython_notebook?:
true
)
expect
(
blob
.
to_partial_path
(
project
)).
to
eq
'notebook'
end
it
'handles Sketch files'
do
blob
=
stubbed_blob
(
text?:
true
,
sketch?:
true
,
binary?:
true
)
expect
(
blob
.
to_partial_path
(
project
)).
to
eq
'sketch'
end
end
describe
'#size_within_svg_limits?'
do
...
...
yarn.lock
View file @
c7132929
...
...
@@ -1245,6 +1245,10 @@ core-js@^2.2.0, core-js@^2.4.0, core-js@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
core-js@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65"
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
...
...
@@ -1581,6 +1585,10 @@ es6-map@^0.1.3:
es6-symbol "~3.1.0"
event-emitter "~0.3.4"
es6-promise@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6"
es6-promise@~4.0.3:
version "4.0.5"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.0.5.tgz#7882f30adde5b240ccfa7f7d78c548330951ae42"
...
...
@@ -2335,6 +2343,10 @@ ignore@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.2.tgz#1c51e1ef53bab6ddc15db4d9ac4ec139eceb3410"
immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
...
...
@@ -2764,6 +2776,20 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.3.6"
jszip-utils@^0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/jszip-utils/-/jszip-utils-0.0.2.tgz#457d5cbca60a1c2e0706e9da2b544e8e7bc50bf8"
jszip@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.1.3.tgz#8a920403b2b1651c0fc126be90192d9080957c37"
dependencies:
core-js "~2.3.0"
es6-promise "~3.0.2"
lie "~3.1.0"
pako "~1.0.2"
readable-stream "~2.0.6"
karma-coverage-istanbul-reporter@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-0.2.0.tgz#5766263338adeb0026f7e4ac7a89a5f056c5642c"
...
...
@@ -2868,6 +2894,12 @@ levn@^0.3.0, levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
lie@~3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e"
dependencies:
immediate "~3.0.5"
load-json-file@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
...
...
@@ -3349,6 +3381,10 @@ pako@~0.2.0:
version "0.2.9"
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
pako@~1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.5.tgz#d2205dfe5b9da8af797e7c163db4d1f84e4600bc"
parse-asn1@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.0.0.tgz#35060f6d5015d37628c770f4e091a0b5a278bc23"
...
...
@@ -3661,7 +3697,7 @@ readable-stream@~1.0.2:
isarray "0.0.1"
string_decoder "~0.10.x"
readable-stream@~2.0.0:
readable-stream@~2.0.0
, readable-stream@~2.0.6
:
version "2.0.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
dependencies:
...
...
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