tiny_mce_plugin_imageselector 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +22 -0
- data/README.rdoc +24 -0
- data/lib/assets/plugins/imageselector/LICENSE +22 -0
- data/lib/assets/plugins/imageselector/README.md +29 -0
- data/lib/assets/plugins/imageselector/css/media_selector.css +80 -0
- data/lib/assets/plugins/imageselector/dialog.htm +48 -0
- data/lib/assets/plugins/imageselector/editor_plugin.js +1 -0
- data/lib/assets/plugins/imageselector/editor_plugin_src.js +81 -0
- data/lib/assets/plugins/imageselector/img/example.gif +0 -0
- data/lib/assets/plugins/imageselector/img/imageselector.png +0 -0
- data/lib/assets/plugins/imageselector/img/spinner.gif +0 -0
- data/lib/assets/plugins/imageselector/js/media_selector.js +562 -0
- data/lib/assets/plugins/imageselector/js/sammy-0.7.0.min.js +5 -0
- data/lib/assets/plugins/imageselector/js/sammy.handlebars-0.7.0.min.js +5 -0
- data/lib/assets/plugins/imageselector/js/sammy.template-0.7.0.min.js +5 -0
- data/lib/assets/plugins/imageselector/langs/en.js +4 -0
- data/lib/assets/plugins/imageselector/langs/en_dlg.js +4 -0
- data/lib/assets/plugins/imageselector/templates/no_results.hb +1 -0
- data/lib/assets/plugins/imageselector/templates/oembed_failed.rb +1 -0
- data/lib/assets/plugins/imageselector/templates/result.hb +18 -0
- data/lib/assets/plugins/imageselector/templates/result_thumbnail.hb +5 -0
- data/lib/assets/plugins/imageselector/templates/results_failed.hb +1 -0
- data/lib/assets/plugins/imageselector/templates/selection.hb +14 -0
- data/lib/assets/plugins/imageselector/templates/sizes_failed.rb +1 -0
- data/lib/assets/plugins/imageselector/templates/source.hb +1 -0
- data/lib/assets/plugins/imageselector/templates/source_next_page_link.hb +1 -0
- data/lib/assets/plugins/imageselector/templates/source_next_page_link_search.hb +6 -0
- data/lib/assets/plugins/imageselector/templates/source_search.hb +9 -0
- data/lib/assets/plugins/imageselector/templates/source_selected.hb +1 -0
- data/lib/assets/plugins/imageselector/templates/source_selected_search.hb +9 -0
- data/lib/assets/plugins/imageselector/templates/upload.hb +1 -0
- data/lib/tiny_mce_plugin_imageselector.rb +23 -0
- data/tiny_mce_plugin_imageselector.gemspec +15 -0
- metadata +100 -0
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (C) 2011 Horowhenua Library Trust
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
= TinyMCE Plugin ImageSelector
|
2
|
+
|
3
|
+
This gem uses the tiny_mce gem's plugin system to install the https://github.com/kete/image_selector_tinymce_plugin plugin.
|
4
|
+
|
5
|
+
= Usage
|
6
|
+
|
7
|
+
To use this plugin, clone the source, gem build, gem install, and add the following after the tiny_mce gem config line:
|
8
|
+
|
9
|
+
config.gem 'tiny_mce' # if you haven't done so already
|
10
|
+
config.gem 'tiny_mce_plugin_imageselector'
|
11
|
+
|
12
|
+
You'll want to adjust your config/tiny_mce.yml file to take advantage of the plugin.
|
13
|
+
|
14
|
+
The imageselector plugin assumes that your site has imageselector config files at /javascripts/image_selector_config/. See the README at https://github.com/kete/image_selector_tinymce_plugin/ for more details on how they are set up.
|
15
|
+
|
16
|
+
= Credits
|
17
|
+
|
18
|
+
tiny_mce_plugin_imageselector was created for the Kete project (http://kete.net.nz) and is maintained by Walter McGinnis <walter a-t katipo dot co dot nz>.
|
19
|
+
|
20
|
+
= License
|
21
|
+
|
22
|
+
tiny_mce_plugin_imageselector is covered by the MIT License. See LICENSE for more information.
|
23
|
+
|
24
|
+
Copyright (C) 2011 Horowhenua Library Trust
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (C) 2011 Horowhenua Library Trust
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# image_selector_tinymce_plugin
|
2
|
+
|
3
|
+
## Description
|
4
|
+
|
5
|
+
Based on media_selector (https://github.com/kete/media_selector) JavaScript mini-application. See media_selector's README for dependencies, etc.
|
6
|
+
|
7
|
+
Image Selector is a jQuery and Sammy.js based mini-application for choosing from a list of providers' media assets (images in this case) that integrates into TinyMCE editor as a plugin.
|
8
|
+
|
9
|
+
Because of its dependency on jQuery, it doesn't currently work with TinyMCE's i18n translation scheme. See http://www.tinymce.com/forum/viewtopic.php?id=16761 for details. Hopefully this issue will be resolved in the future. In the meantime, translate_i18n is set to false.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Copy the contents of this directory to directory called imageselector under your TinyMCE install's plugins director. Configure TinyMCE to use it via the init declaration.
|
14
|
+
|
15
|
+
You'll also need to set up JSON files for your image providers and the size you want. IMPORTANT! These are assumed to be under /javascripts/image_selector_config/ on your site. See https://github.com/kete/media_selector/blob/master/data/providers.json and https://github.com/kete/media_selector/blob/master/data/sizes.json for how (you'll need to adjust URLs, etc. to suit).
|
16
|
+
|
17
|
+
## Dependencies
|
18
|
+
|
19
|
+
TinyMCE provides the plugin API that we are integrating with.
|
20
|
+
|
21
|
+
jQuery (through a link to Google's CDN), Handlebars.js, and Sammy.js along with some Sammy.js plugins that are included in the javascripts directory.
|
22
|
+
|
23
|
+
## Author
|
24
|
+
|
25
|
+
image_selector_tinymce_plugin was created for the Kete project (http://kete.net.nz) and is maintained by Walter McGinnis <walter a-t katipo dot co dot nz>.
|
26
|
+
|
27
|
+
## License
|
28
|
+
|
29
|
+
image_selector_tinymce_plugin is covered by the MIT License. See LICENSE for more information.
|
@@ -0,0 +1,80 @@
|
|
1
|
+
body {
|
2
|
+
font-family: sans-serif;
|
3
|
+
}
|
4
|
+
|
5
|
+
#providers {
|
6
|
+
float: left;
|
7
|
+
width: 30%;
|
8
|
+
}
|
9
|
+
|
10
|
+
#providers ul {
|
11
|
+
padding-left: 0;
|
12
|
+
margin-left: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
#providers li.upload-link {
|
16
|
+
list-style-type: none;
|
17
|
+
}
|
18
|
+
|
19
|
+
#providers li.source {
|
20
|
+
list-style-type: none;
|
21
|
+
}
|
22
|
+
|
23
|
+
#providers li.source-selected {
|
24
|
+
list-style-type: none;
|
25
|
+
}
|
26
|
+
|
27
|
+
#results {
|
28
|
+
border-left: #999 1px solid;
|
29
|
+
padding-left: 5%;
|
30
|
+
float: right;
|
31
|
+
width: 65%;
|
32
|
+
}
|
33
|
+
|
34
|
+
#results li.result-grid {
|
35
|
+
float: left;
|
36
|
+
margin: 5px;
|
37
|
+
list-style-type:none;
|
38
|
+
width: 250px;
|
39
|
+
}
|
40
|
+
|
41
|
+
.result-thumbnail-select {
|
42
|
+
display: none;
|
43
|
+
text-align: center;
|
44
|
+
}
|
45
|
+
|
46
|
+
a.result-size-choose {
|
47
|
+
text-align: center;
|
48
|
+
}
|
49
|
+
|
50
|
+
li.size-choice {
|
51
|
+
float: left;
|
52
|
+
margin: 5px;
|
53
|
+
list-style-type:none;
|
54
|
+
}
|
55
|
+
|
56
|
+
div.size-name {
|
57
|
+
text-transform: capitalize;
|
58
|
+
}
|
59
|
+
|
60
|
+
#home-link {
|
61
|
+
clear: both;
|
62
|
+
}
|
63
|
+
|
64
|
+
textarea.selection-embed {
|
65
|
+
width: 600px;
|
66
|
+
height: 120px;
|
67
|
+
border: 3px solid #cccccc;
|
68
|
+
padding: 5px;
|
69
|
+
}
|
70
|
+
|
71
|
+
img.spinner {
|
72
|
+
display: block;
|
73
|
+
margin-left: auto;
|
74
|
+
margin-right: auto;
|
75
|
+
}
|
76
|
+
|
77
|
+
#next-page, #search-form-next {
|
78
|
+
clear: both;
|
79
|
+
width: 100%;
|
80
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
3
|
+
<head>
|
4
|
+
<title>Select image</title>
|
5
|
+
|
6
|
+
<link rel="stylesheet" type="text/css" href="css/media_selector.css" />
|
7
|
+
|
8
|
+
<script type="text/javascript" src="../../tiny_mce_popup.js?v={tinymce_version}"></script>
|
9
|
+
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
|
13
|
+
<div id="main">
|
14
|
+
|
15
|
+
<div id="providers">
|
16
|
+
<div id="providers-spinner" style="display: none"><img class="spinner" src="img/spinner.gif" width="16" height="16" alt="loading indicator. "></div>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<div id="results">
|
20
|
+
<h2 class="section-header"></h2>
|
21
|
+
<div id="results-spinner" style="display: none"><img class="spinner" src="img/spinner.gif" width="16" height="16" alt="loading indicator. "></div>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<div style="clear:both;"></div>
|
25
|
+
</div>
|
26
|
+
|
27
|
+
<div id="page-spinner"><img class="spinner" src="img/spinner.gif" width="16" height="16" alt="loading indicator. "></div>
|
28
|
+
|
29
|
+
<div class="mceActionPanel">
|
30
|
+
<input type="button" id="cancel" name="cancel" value="cancel" onclick="tinyMCEPopup.close();" />
|
31
|
+
</div>
|
32
|
+
|
33
|
+
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
|
34
|
+
|
35
|
+
<script type="text/javascript">
|
36
|
+
jQuery.noConflict();
|
37
|
+
var mediaSelectorConfig = { directory: '/javascripts/image_selector_config/' };
|
38
|
+
</script>
|
39
|
+
|
40
|
+
<script src="js/sammy-0.7.0.min.js"></script>
|
41
|
+
<script src="js/sammy.template-0.7.0.min.js"></script>
|
42
|
+
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.0.beta2/handlebars.min.js"></script>
|
43
|
+
<script src="js/sammy.handlebars-0.7.0.min.js"></script>
|
44
|
+
|
45
|
+
<script src="js/media_selector.js"></script>
|
46
|
+
|
47
|
+
</body>
|
48
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
(function(){tinymce.PluginManager.requireLangPack('imageselector');tinymce.create('tinymce.plugins.ImageselectorPlugin',{init:function(ed,url){ed.addCommand('mceImageselector',function(){ed.windowManager.open({file:url+'/dialog.htm',width:900+parseInt(ed.getLang('imageselector.delta_width',0)),height:500+parseInt(ed.getLang('imageselector.delta_height',0)),inline:1,translate_i18n: false},{plugin_url:url})});ed.addButton('imageselector',{title:'imageselector.desc',cmd:'mceImageselector',image:url+'/img/imageselector.png'});ed.onNodeChange.add(function(ed,cm,n){cm.setActive('imageselector',n.nodeName=='IMG')})},createControl:function(n,cm){return null},getInfo:function(){return{longname:'Imageselector plugin',author:'Walter McGinnis',authorurl:'http://waltermcginnis.com',infourl:'https://github.com/kete/image_selector_tinymce_plugin',version:"0.2"}}});tinymce.PluginManager.add('imageselector',tinymce.plugins.ImageselectorPlugin)})();
|
@@ -0,0 +1,81 @@
|
|
1
|
+
/**
|
2
|
+
* editor_plugin_src.js
|
3
|
+
*
|
4
|
+
* Copyright 2011, Horowhenua Library Trust
|
5
|
+
* Released under MIT License, see included LICENSE file
|
6
|
+
*/
|
7
|
+
|
8
|
+
(function() {
|
9
|
+
// Load plugin specific language pack
|
10
|
+
tinymce.PluginManager.requireLangPack('imageselector');
|
11
|
+
|
12
|
+
tinymce.create('tinymce.plugins.ImageselectorPlugin', {
|
13
|
+
/**
|
14
|
+
* Initializes the plugin, this will be executed after the plugin has been created.
|
15
|
+
* This call is done before the editor instance has finished it's initialization so use the onInit event
|
16
|
+
* of the editor instance to intercept that event.
|
17
|
+
*
|
18
|
+
* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
|
19
|
+
* @param {string} url Absolute URL to where the plugin is located.
|
20
|
+
*/
|
21
|
+
init : function(ed, url) {
|
22
|
+
// Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceImageselector');
|
23
|
+
ed.addCommand('mceImageselector', function() {
|
24
|
+
ed.windowManager.open({
|
25
|
+
file : url + '/dialog.htm',
|
26
|
+
width : 900 + parseInt(ed.getLang('imageselector.delta_width', 0)),
|
27
|
+
height : 500 + parseInt(ed.getLang('imageselector.delta_height', 0)),
|
28
|
+
inline : 1,
|
29
|
+
translate_i18n: false
|
30
|
+
}, {
|
31
|
+
plugin_url : url // Plugin absolute URL
|
32
|
+
});
|
33
|
+
});
|
34
|
+
|
35
|
+
// Register imageselector button
|
36
|
+
ed.addButton('imageselector', {
|
37
|
+
title : 'imageselector.desc',
|
38
|
+
cmd : 'mceImageselector',
|
39
|
+
image : url + '/img/imageselector.png'
|
40
|
+
});
|
41
|
+
|
42
|
+
// Add a node change handler, selects the button in the UI when a image is selected
|
43
|
+
ed.onNodeChange.add(function(ed, cm, n) {
|
44
|
+
cm.setActive('imageselector', n.nodeName == 'IMG');
|
45
|
+
});
|
46
|
+
},
|
47
|
+
|
48
|
+
/**
|
49
|
+
* Creates control instances based in the incomming name. This method is normally not
|
50
|
+
* needed since the addButton method of the tinymce.Editor class is a more easy way of adding buttons
|
51
|
+
* but you sometimes need to create more complex controls like listboxes, split buttons etc then this
|
52
|
+
* method can be used to create those.
|
53
|
+
*
|
54
|
+
* @param {String} n Name of the control to create.
|
55
|
+
* @param {tinymce.ControlManager} cm Control manager to use inorder to create new control.
|
56
|
+
* @return {tinymce.ui.Control} New control instance or null if no control was created.
|
57
|
+
*/
|
58
|
+
createControl : function(n, cm) {
|
59
|
+
return null;
|
60
|
+
},
|
61
|
+
|
62
|
+
/**
|
63
|
+
* Returns information about the plugin as a name/value array.
|
64
|
+
* The current keys are longname, author, authorurl, infourl and version.
|
65
|
+
*
|
66
|
+
* @return {Object} Name/value array containing information about the plugin.
|
67
|
+
*/
|
68
|
+
getInfo : function() {
|
69
|
+
return {
|
70
|
+
longname : 'Imageselector plugin',
|
71
|
+
author : 'Walter McGinnis',
|
72
|
+
authorurl : 'http://waltermcginnis.com',
|
73
|
+
infourl : 'https://github.com/kete/image_selector_tinymce_plugin',
|
74
|
+
version : "0.2"
|
75
|
+
};
|
76
|
+
}
|
77
|
+
});
|
78
|
+
|
79
|
+
// Register plugin
|
80
|
+
tinymce.PluginManager.add('imageselector', tinymce.plugins.ImageselectorPlugin);
|
81
|
+
})();
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,562 @@
|
|
1
|
+
/**
|
2
|
+
* media_selector.js
|
3
|
+
*
|
4
|
+
* Copyright 2011, Horowhenua Library Trust
|
5
|
+
* Released under MIT License, see included LICENSE file
|
6
|
+
*
|
7
|
+
* expects a mediaSelectorConfig object to be defined before this file is run
|
8
|
+
* it should look something like this:
|
9
|
+
*
|
10
|
+
* { directory: path/to/directory/for/config/files/ }
|
11
|
+
*
|
12
|
+
*/
|
13
|
+
(function($) {
|
14
|
+
var app = $.sammy('#main', function() {
|
15
|
+
this.use(Sammy.Handlebars, 'hb');
|
16
|
+
|
17
|
+
this.helpers({
|
18
|
+
stubUrlForResult: function() {
|
19
|
+
return document.URL.split('#')[0] + '#/results/'
|
20
|
+
},
|
21
|
+
providerListIdFor: function(providerIndex) {
|
22
|
+
return 'provider-list-' + providerIndex;
|
23
|
+
},
|
24
|
+
providerTitleIdFor: function(providerIndex) {
|
25
|
+
return 'provider-title-' + providerIndex;
|
26
|
+
},
|
27
|
+
setProviders: function(context) {
|
28
|
+
$('#providers-spinner').hide();
|
29
|
+
|
30
|
+
$.each(context.providers, function(i, provider) {
|
31
|
+
$('#providers').append("<h3 class=\"provider-title\" id=\"" + context.providerTitleIdFor(i) + "\">" + provider.title + '</h3>');
|
32
|
+
$('#providers').append("<ul id=\"" + context.providerListIdFor(i) + "\"></div>");
|
33
|
+
});
|
34
|
+
},
|
35
|
+
sourceIdFor: function(providerIndex, sourceIndex) {
|
36
|
+
return 'source-' + providerIndex + '-' + sourceIndex;
|
37
|
+
},
|
38
|
+
sourceTemplateStub: 'templates/source'
|
39
|
+
});
|
40
|
+
|
41
|
+
// load providers data for every request
|
42
|
+
this.around(function(callback) {
|
43
|
+
var context = this;
|
44
|
+
this.load(mediaSelectorConfig.directory + 'providers.json')
|
45
|
+
.then(function(providers) {
|
46
|
+
context.providers = providers;
|
47
|
+
})
|
48
|
+
.then(callback);
|
49
|
+
});
|
50
|
+
|
51
|
+
// index has two panes; providers with their sources and results for selected source
|
52
|
+
// which in index case (none specified) is first source of first provider
|
53
|
+
this.get('#/', function(context) {
|
54
|
+
// get the results from default_source
|
55
|
+
// assumes that first provider's first source isn't a search
|
56
|
+
var defaultSource = this.providers[0].sources[0];
|
57
|
+
|
58
|
+
defaultSource.sourceId = context.sourceIdFor(0, 0);
|
59
|
+
|
60
|
+
defaultSource['provider_title'] = this.providers[0]['title'];
|
61
|
+
|
62
|
+
this.trigger('updateSourceTo', defaultSource);
|
63
|
+
|
64
|
+
this.trigger('updateResultsFor', defaultSource);
|
65
|
+
});
|
66
|
+
|
67
|
+
// results for a give source id
|
68
|
+
// selected source indicated in providers source list
|
69
|
+
function getSource(context) {
|
70
|
+
var idIndexes = context.params['id'].split('-');
|
71
|
+
var providerIndex = idIndexes[1],
|
72
|
+
sourceIndex = idIndexes[2],
|
73
|
+
the_provider = context.providers[providerIndex];
|
74
|
+
|
75
|
+
// get the results from selected source
|
76
|
+
var selectedSource = the_provider.sources[sourceIndex];
|
77
|
+
|
78
|
+
selectedSource['provider_title'] = the_provider['title'];
|
79
|
+
|
80
|
+
context.trigger('updateSourceTo', selectedSource);
|
81
|
+
|
82
|
+
context.trigger('updateResultsFor', selectedSource);
|
83
|
+
}
|
84
|
+
|
85
|
+
// these are the same, except for addition of pagination in route
|
86
|
+
this.get('#/:id', function(context) { getSource(context) });
|
87
|
+
this.get('#/:id/page/:page_number', function(context) { getSource(context) });
|
88
|
+
|
89
|
+
// same as above, but target for search form for a source
|
90
|
+
function postSearchOfSource(context) {
|
91
|
+
var idIndexes = context.params['id'].split('-');
|
92
|
+
var providerIndex = idIndexes[1],
|
93
|
+
sourceIndex = idIndexes[2],
|
94
|
+
the_provider = context.providers[providerIndex];
|
95
|
+
|
96
|
+
// get the results from selected source
|
97
|
+
var selectedSource = the_provider.sources[sourceIndex];
|
98
|
+
|
99
|
+
selectedSource['provider_title'] = the_provider['title'];
|
100
|
+
|
101
|
+
context.trigger('updateSourceTo', selectedSource);
|
102
|
+
|
103
|
+
context.trigger('updateResultsFor', selectedSource);
|
104
|
+
}
|
105
|
+
|
106
|
+
// same except for pagination support
|
107
|
+
this.post('#/:id', function(context) { postSearchOfSource(context) });
|
108
|
+
this.post('#/:id/page/:page_number', function(context) { postSearchOfSource(context) });
|
109
|
+
|
110
|
+
// a given result's display
|
111
|
+
// show available sizes (based on requests to oembed provider for result id)
|
112
|
+
// so user may choose which size
|
113
|
+
this.get('#/results/:id', function(context) {
|
114
|
+
$('#results').fadeOut();
|
115
|
+
$('#providers').fadeOut();
|
116
|
+
$('#page-spinner').fadeIn();
|
117
|
+
|
118
|
+
// params['id'] decodes to normal url, but we need escaped version
|
119
|
+
var resultUrl = escape(this.params['id']);
|
120
|
+
|
121
|
+
var result = {
|
122
|
+
url: resultUrl,
|
123
|
+
hasAllSizes: false,
|
124
|
+
hasSizesError: false,
|
125
|
+
render: function(context) {
|
126
|
+
this.updateWithNeededSizesThenRender(context);
|
127
|
+
},
|
128
|
+
updateWithNeededSizesThenRender: function(context) {
|
129
|
+
result = this;
|
130
|
+
|
131
|
+
if (result.hasAllSizes || result.hasSizesError) {
|
132
|
+
if (!(result.hasSizeError)) {
|
133
|
+
// rearrange result to be an array
|
134
|
+
// so we don't need to know about the keys of sizes in the template
|
135
|
+
var resultSizes = [],
|
136
|
+
resultTitle = '',
|
137
|
+
resultAuthor= {};
|
138
|
+
|
139
|
+
var sizeCount = 0;
|
140
|
+
|
141
|
+
$.each(sizesNames(context), function(i, sizeName) {
|
142
|
+
result[sizeName]["size_name"] = sizeName;
|
143
|
+
|
144
|
+
var currentSize = {};
|
145
|
+
|
146
|
+
$.each(context.sizes, function(i, sizeOption) {
|
147
|
+
if (sizeName === sizeOption.name) {
|
148
|
+
currentSize = sizeOption;
|
149
|
+
return false;
|
150
|
+
}
|
151
|
+
});
|
152
|
+
|
153
|
+
result[sizeName]["oembed_url"] = encodeURIComponent(result.oembedUrlFor(currentSize));
|
154
|
+
|
155
|
+
resultSizes.push(result[sizeName]);
|
156
|
+
|
157
|
+
sizeCount++;
|
158
|
+
|
159
|
+
if (sizeCount === 1) {
|
160
|
+
resultTitle = result[sizeName].title;
|
161
|
+
|
162
|
+
resultAuthor = {
|
163
|
+
url: result[sizeName].author_url,
|
164
|
+
name: result[sizeName].author_name
|
165
|
+
};
|
166
|
+
}
|
167
|
+
});
|
168
|
+
|
169
|
+
var resultForTemplate = {
|
170
|
+
result_title: resultTitle,
|
171
|
+
result_author_url: resultAuthor.url,
|
172
|
+
result_author_name: resultAuthor.name,
|
173
|
+
sizes: resultSizes
|
174
|
+
};
|
175
|
+
|
176
|
+
$('#page-spinner').fadeOut();
|
177
|
+
// this views takes whole area of page
|
178
|
+
context.partial('templates/result.hb', resultForTemplate);
|
179
|
+
}
|
180
|
+
} else {
|
181
|
+
// check sizes that are already complete
|
182
|
+
var neededSizes = [];
|
183
|
+
|
184
|
+
$.each(sizesNames(context), function(i, sizeName) {
|
185
|
+
// if undefined for sizeName
|
186
|
+
// push to neededSizes
|
187
|
+
if (typeof(result[sizeName]) == "undefined") {
|
188
|
+
neededSizes.push(sizeName);
|
189
|
+
}
|
190
|
+
});
|
191
|
+
|
192
|
+
if (neededSizes.length === 0) {
|
193
|
+
// this will complete recursion during next call
|
194
|
+
result.hasAllSizes = true;
|
195
|
+
result.updateWithNeededSizesThenRender(context);
|
196
|
+
} else {
|
197
|
+
// get the first in neededSizes
|
198
|
+
var nextSizeName = neededSizes.shift();
|
199
|
+
size = {};
|
200
|
+
|
201
|
+
$.each(context.sizes, function(i, sizeOption) {
|
202
|
+
if (nextSizeName === sizeOption.name) {
|
203
|
+
size = sizeOption;
|
204
|
+
return false;
|
205
|
+
}
|
206
|
+
});
|
207
|
+
|
208
|
+
// and append what is returned from oembed to result object for that size name
|
209
|
+
$.get(result.oembedUrlFor(size))
|
210
|
+
.success(function(response) {
|
211
|
+
// TODO: make this detect xml or json and parse accordingly
|
212
|
+
// TODO: this is limited to same domain only for now, update to handle JSONP
|
213
|
+
// probably need to switch to $.ajax and more complete parameters call for jsonp
|
214
|
+
result[size.name] = $.parseJSON(response);
|
215
|
+
|
216
|
+
// scope issue, response is set in calling scope, and not getting set with recursive call
|
217
|
+
result.updateWithNeededSizesThenRender(context);
|
218
|
+
})
|
219
|
+
.error(function() {
|
220
|
+
context.log("oembed response failed for " + size.name);
|
221
|
+
context.partial('templates/oembed_failed.hb', { oembed_url: oembedUrlFor(size) } );
|
222
|
+
// this will break cycle of recursive calls
|
223
|
+
result.hasSizesError = true;
|
224
|
+
result.updateWithNeededSizesThenRender(context);
|
225
|
+
});
|
226
|
+
}
|
227
|
+
}
|
228
|
+
},
|
229
|
+
oembedUrlFor: function(size) {
|
230
|
+
var oembed_url = result.provider.oembed_endpoint + '?url=' + result.url;
|
231
|
+
oembed_url += '&maxwidth=' + size.width;
|
232
|
+
oembed_url += '&maxheight=' + size.height;
|
233
|
+
return oembed_url;
|
234
|
+
}
|
235
|
+
};
|
236
|
+
|
237
|
+
// look up provider oembed endpoint
|
238
|
+
// TODO: replace this with something that doesn't iterate through each provider
|
239
|
+
$.each(context.providers, function(i, provider) {
|
240
|
+
// TODO: make sure this works with IE8
|
241
|
+
if (result.url.indexOf(provider.domain) != -1) {
|
242
|
+
result["provider"] = provider;
|
243
|
+
return false;
|
244
|
+
}
|
245
|
+
});
|
246
|
+
|
247
|
+
$.when(sizesLoadedInto(context))
|
248
|
+
.then(function() {
|
249
|
+
result.render(context)
|
250
|
+
});
|
251
|
+
|
252
|
+
});
|
253
|
+
|
254
|
+
// this gives selected result and the user's selected size
|
255
|
+
// and outputs end result of oembed request for html to embed the result at the selected size
|
256
|
+
this.get('#/selections/:id', function(context) {
|
257
|
+
$('#result-description-and-sizes').fadeOut();
|
258
|
+
$('#page-spinner').fadeIn();
|
259
|
+
|
260
|
+
// params['id'] decodes to normal url, but we need escaped version
|
261
|
+
var oembedUrl = this.params['id'];
|
262
|
+
|
263
|
+
$.get(oembedUrl)
|
264
|
+
.success(function(response) {
|
265
|
+
// TODO: make this detect xml or json and parse accordingly
|
266
|
+
// TODO: this is limited to same domain only for now, update to handle JSONP
|
267
|
+
// probably need to switch to $.ajax and more complete parameters call for jsonp
|
268
|
+
var selectionFromResponse = $.parseJSON(response);
|
269
|
+
|
270
|
+
// add alt value for selection so we can use it in template
|
271
|
+
var alt = selectionFromResponse.title;
|
272
|
+
|
273
|
+
// add a full stop to title for better accessibility
|
274
|
+
// start by stripping off trailing spaces for ease our following logic
|
275
|
+
alt = alt.replace(/\s+$/g, "");
|
276
|
+
|
277
|
+
if (alt.charAt( alt.length-1 ) === ".") {
|
278
|
+
alt = alt + '. ';
|
279
|
+
}
|
280
|
+
|
281
|
+
selectionFromResponse.alt = alt;
|
282
|
+
|
283
|
+
// look up matching provider, check for code to call with selectionFromResponse
|
284
|
+
var selectionProvider;
|
285
|
+
|
286
|
+
$.each(context.providers, function(i, provider) {
|
287
|
+
// TODO: make sure this works with IE8
|
288
|
+
if (oembedUrl.indexOf(provider.domain) != -1) {
|
289
|
+
selectionProvider = provider;
|
290
|
+
return false;
|
291
|
+
}
|
292
|
+
});
|
293
|
+
|
294
|
+
$('#page-spinner').fadeOut();
|
295
|
+
|
296
|
+
if (selectionProvider !== '' &&
|
297
|
+
typeof selectionProvider !== 'undefined' &&
|
298
|
+
selectionProvider.insertIntoEditor !== '' &&
|
299
|
+
typeof selectionProvider.insertIntoEditor !== 'undefined') {
|
300
|
+
|
301
|
+
if (selectionProvider.insertIntoEditor.editor !== '' &&
|
302
|
+
typeof selectionProvider.insertIntoEditor.editor !== 'undefined') {
|
303
|
+
|
304
|
+
// TODO: tweak this based on provider.media_type in future
|
305
|
+
var valueToInsert = '<img src="' + selectionFromResponse.url + '" width="';
|
306
|
+
valueToInsert = valueToInsert + selectionFromResponse.width;
|
307
|
+
valueToInsert = valueToInsert + '" height="' + selectionFromResponse.height;
|
308
|
+
valueToInsert = valueToInsert + '" alt="' + selectionFromResponse.alt + '"> by <a href="';
|
309
|
+
valueToInsert = valueToInsert + selectionFromResponse.author_url + '">' + selectionFromResponse.author_name +'</a>';
|
310
|
+
|
311
|
+
if (selectionProvider.insertIntoEditor.editor === 'TinyMCE') {
|
312
|
+
tinyMCEPopup.editor.execCommand('mceInsertContent', false, valueToInsert);
|
313
|
+
tinyMCEPopup.close();
|
314
|
+
}
|
315
|
+
}
|
316
|
+
selectionProvider.processFinal(selectionFromResponse);
|
317
|
+
|
318
|
+
} else {
|
319
|
+
// otherwise we render template
|
320
|
+
// this view takes whole of view
|
321
|
+
context.partial('templates/selection.hb', selectionFromResponse);
|
322
|
+
}
|
323
|
+
})
|
324
|
+
.error(function() {
|
325
|
+
context.log("oembed selection response failed for " + oembedUrl);
|
326
|
+
context.partial('templates/oembed_failed.hb', { oembed_url: oembedUrl });
|
327
|
+
});
|
328
|
+
});
|
329
|
+
|
330
|
+
function sizesLoadedInto(context) {
|
331
|
+
return $.get(mediaSelectorConfig.directory + 'sizes.json')
|
332
|
+
.success(function(response) {
|
333
|
+
// plain response is probably already json object if parse returns null
|
334
|
+
var responseAsJSON = response;
|
335
|
+
|
336
|
+
if (typeof(responseAsJSON) == 'string' || responseAsJSON === '' || typeof(responseAsJSON) === 'undefined') {
|
337
|
+
responseAsJSON = $.parseJSON(response);
|
338
|
+
}
|
339
|
+
|
340
|
+
context.sizes = responseAsJSON;
|
341
|
+
})
|
342
|
+
.error(function() {
|
343
|
+
context.log("response failed");
|
344
|
+
context.partial('templates/sizes_failed.hb');
|
345
|
+
});
|
346
|
+
}
|
347
|
+
|
348
|
+
function sizesNames(context) {
|
349
|
+
var names = [];
|
350
|
+
$.each(context.sizes, function(i, size) {
|
351
|
+
names.push(size.name);
|
352
|
+
});
|
353
|
+
return names;
|
354
|
+
}
|
355
|
+
|
356
|
+
// route = #/id (id of source) - in form provider index - source index
|
357
|
+
// i.e. 0-1 would be the first provider's second source
|
358
|
+
// route = #/id (id of source) + params[search_terms] for searchable source
|
359
|
+
// route for results = #/results/id where id is url
|
360
|
+
// add to results:
|
361
|
+
// or upload image -> requests url for upload and returns to #/results/id
|
362
|
+
// or add image URL
|
363
|
+
// add to result detail page a "back" button
|
364
|
+
this.bind('updateSourceTo', function(e, selectedSource) {
|
365
|
+
$('#page-spinner').hide();
|
366
|
+
$('#results-list').text('');
|
367
|
+
$('h3.no-results-title').hide();
|
368
|
+
$('#results-spinner').fadeIn();
|
369
|
+
|
370
|
+
context = this;
|
371
|
+
|
372
|
+
var searchTerms = this.params['search_terms'];
|
373
|
+
|
374
|
+
if ($('h3.provider-title').length === 0) {
|
375
|
+
this.setProviders(context);
|
376
|
+
}
|
377
|
+
|
378
|
+
$.each(this.providers, function(i, provider) {
|
379
|
+
var providerIndex = i;
|
380
|
+
var providerListId = context.providerListIdFor(providerIndex);
|
381
|
+
|
382
|
+
$('#' + providerListId).text('');
|
383
|
+
|
384
|
+
$.each(provider.sources, function(i, source) {
|
385
|
+
source.sourceId = context.sourceIdFor(providerIndex, i);
|
386
|
+
|
387
|
+
var appropriate_template = context.sourceTemplateStub;
|
388
|
+
|
389
|
+
if (selectedSource && source === selectedSource) {
|
390
|
+
appropriate_template += '_selected';
|
391
|
+
}
|
392
|
+
|
393
|
+
if (source.searchable_stub) {
|
394
|
+
appropriate_template += '_search';
|
395
|
+
|
396
|
+
if (searchTerms) {
|
397
|
+
source.value = searchTerms;
|
398
|
+
} else {
|
399
|
+
source.value = '';
|
400
|
+
}
|
401
|
+
}
|
402
|
+
|
403
|
+
appropriate_template += '.hb';
|
404
|
+
|
405
|
+
context.render(appropriate_template, source)
|
406
|
+
.appendTo("#" + providerListId);
|
407
|
+
});
|
408
|
+
|
409
|
+
// HACK: for some reason when '&target_service=' + targetService is added, handlebars fails to parse {{url}} correctly
|
410
|
+
// this worksaround the issue in an ugly fashion
|
411
|
+
provider.upload_startpoint['service_target_param'] = '&service_target=' + escape(context.stubUrlForResult());
|
412
|
+
|
413
|
+
if (typeof(provider.upload_startpoint) != "undefined") {
|
414
|
+
context.render('templates/upload.hb', provider.upload_startpoint)
|
415
|
+
.appendTo("#" + providerListId);
|
416
|
+
}
|
417
|
+
});
|
418
|
+
});
|
419
|
+
|
420
|
+
// get each of the entries up to limit
|
421
|
+
// render in template for result
|
422
|
+
// append to #results
|
423
|
+
// animate the results each being added
|
424
|
+
this.bind('updateResultsFor', function(e, source) {
|
425
|
+
context = this;
|
426
|
+
|
427
|
+
var searchTerms = this.params['search_terms'],
|
428
|
+
pageNumber = this.params['page_number'],
|
429
|
+
fullUrl = source.url;
|
430
|
+
|
431
|
+
if (searchTerms) {
|
432
|
+
fullUrl += searchTerms;
|
433
|
+
}
|
434
|
+
|
435
|
+
if (typeof(source['limit_parameter']) !== "undefined" &&
|
436
|
+
typeof(source['display_limit']) !== "undefined") {
|
437
|
+
|
438
|
+
var limit_parameter_adjusted = source.limit_parameter;
|
439
|
+
|
440
|
+
if (searchTerms) {
|
441
|
+
limit_parameter_adjusted = limit_parameter_adjusted.replace(/^\?/, "&");
|
442
|
+
}
|
443
|
+
|
444
|
+
fullUrl += limit_parameter_adjusted + source.display_limit;
|
445
|
+
|
446
|
+
if (source['page_parameter'] !== '' && typeof(source['page_parameter']) !== "undefined") {
|
447
|
+
if (pageNumber === '' || typeof pageNumber === 'undefined') {
|
448
|
+
pageNumber = 1;
|
449
|
+
}
|
450
|
+
|
451
|
+
source.nextPage = parseInt(pageNumber) + 1;
|
452
|
+
fullUrl += source.page_parameter + pageNumber.toString();
|
453
|
+
}
|
454
|
+
}
|
455
|
+
|
456
|
+
var resultRequest = $.get(fullUrl)
|
457
|
+
.success(function( response ) {
|
458
|
+
$('#results-spinner').hide();
|
459
|
+
$('#results-list').text('');
|
460
|
+
|
461
|
+
var resultsTitle = source.name + ' ' + source.media_type_plural;
|
462
|
+
|
463
|
+
if (searchTerms) {
|
464
|
+
resultsTitle = resultsTitle + ' for "' + searchTerms + '"';
|
465
|
+
source.searchTerms = searchTerms;
|
466
|
+
}
|
467
|
+
|
468
|
+
resultsTitle = resultsTitle + '(click to select)';
|
469
|
+
|
470
|
+
$('#results h2').text(resultsTitle);
|
471
|
+
|
472
|
+
var itemsLimit = source.display_limit;
|
473
|
+
var itemsCount = 0;
|
474
|
+
|
475
|
+
// items from rss items or atom entries
|
476
|
+
// i want image thumbnail src (enclosure or media:thumbnail)
|
477
|
+
// title
|
478
|
+
// full url (link)
|
479
|
+
var items = $(response).find('item');
|
480
|
+
|
481
|
+
// handle Atom
|
482
|
+
if (items.length === 0) {
|
483
|
+
items = $(response).find('entry');
|
484
|
+
}
|
485
|
+
|
486
|
+
if (items.length) {
|
487
|
+
$('#results').append("<ul id=\"results-list\">");
|
488
|
+
|
489
|
+
items.each(function() {
|
490
|
+
if (itemsCount === itemsLimit) { return false; }
|
491
|
+
|
492
|
+
var resultThumbnail = $(this).find("thumbnail").attr('url');
|
493
|
+
|
494
|
+
if (!resultThumbnail || 0 === resultThumbnail.length) {
|
495
|
+
// TODO: currently broken
|
496
|
+
$(this).find('description').each(function() {
|
497
|
+
resultThumbnail = $(this).find('img').attr('src');
|
498
|
+
});
|
499
|
+
}
|
500
|
+
|
501
|
+
var resultTitle = $(this).find('title').text();
|
502
|
+
var resultLink = $(this).find('link').text();
|
503
|
+
|
504
|
+
var result = {
|
505
|
+
title: resultTitle,
|
506
|
+
link: resultLink,
|
507
|
+
link_escaped: encodeURIComponent(resultLink),
|
508
|
+
thumbnail_url: resultThumbnail
|
509
|
+
}
|
510
|
+
|
511
|
+
context.render('templates/result_thumbnail.hb', result)
|
512
|
+
.appendTo('#results-list');
|
513
|
+
|
514
|
+
itemsCount++;
|
515
|
+
});
|
516
|
+
|
517
|
+
$('#results').append("</ul>");
|
518
|
+
|
519
|
+
if (source.nextPage !== '' && typeof source.nextPage !== 'undefined') {
|
520
|
+
// clear them, if they exist, so we can replace them later
|
521
|
+
$('#search-form-next').remove();
|
522
|
+
$('#next-page').remove();
|
523
|
+
|
524
|
+
// if we have less items than display_limit,
|
525
|
+
// we don't have any more pages of results
|
526
|
+
// if equal, we assume there are more (faulty assumption, but relatively safe)
|
527
|
+
if (items.length === source.display_limit) {
|
528
|
+
if (searchTerms) {
|
529
|
+
context.render('templates/source_next_page_link_search.hb', source)
|
530
|
+
.appendTo('#results');
|
531
|
+
} else {
|
532
|
+
context.render('templates/source_next_page_link.hb', source)
|
533
|
+
.appendTo('#results');
|
534
|
+
}
|
535
|
+
}
|
536
|
+
}
|
537
|
+
} else {
|
538
|
+
context.render('templates/no_results.hb', source)
|
539
|
+
.appendTo($('#results'));
|
540
|
+
}
|
541
|
+
})
|
542
|
+
.error(function() {
|
543
|
+
$('#results-spinner').hide();
|
544
|
+
|
545
|
+
// clear them, as they are no longer relevant
|
546
|
+
$('#search-form-next').remove();
|
547
|
+
$('#next-page').remove();
|
548
|
+
|
549
|
+
context.render('templates/results_failed.hb', source)
|
550
|
+
.appendTo($('#results'));
|
551
|
+
});
|
552
|
+
});
|
553
|
+
|
554
|
+
|
555
|
+
});
|
556
|
+
|
557
|
+
$(function() {
|
558
|
+
app.run('#/');
|
559
|
+
});
|
560
|
+
|
561
|
+
})(jQuery);
|
562
|
+
|
@@ -0,0 +1,5 @@
|
|
1
|
+
// -- Sammy.js -- /sammy.js
|
2
|
+
// http://sammyjs.org
|
3
|
+
// Version: 0.7.0
|
4
|
+
// Built: 2011-07-30 16:55:53 -0700
|
5
|
+
(function(h,j){var p,g="([^/]+)",k=/:([\w\d]+)/g,l=/\?([^#]*)$/,c=function(q){return Array.prototype.slice.call(q)},d=function(q){return Object.prototype.toString.call(q)==="[object Function]"},m=function(q){return Object.prototype.toString.call(q)==="[object Array]"},i=function(q){return decodeURIComponent((q||"").replace(/\+/g," "))},b=encodeURIComponent,f=function(q){return String(q).replace(/&(?!\w+;)/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},n=function(q){return function(r,s){return this.route.apply(this,[q,r,s])}},a={},o=!!(j.history&&history.pushState),e=[];p=function(){var r=c(arguments),s,q;p.apps=p.apps||{};if(r.length===0||r[0]&&d(r[0])){return p.apply(p,["body"].concat(r))}else{if(typeof(q=r.shift())=="string"){s=p.apps[q]||new p.Application();s.element_selector=q;if(r.length>0){h.each(r,function(t,u){s.use(u)})}if(s.element_selector!=q){delete p.apps[q]}p.apps[s.element_selector]=s;return s}}};p.VERSION="0.7.0";p.addLogger=function(q){e.push(q)};p.log=function(){var q=c(arguments);q.unshift("["+Date()+"]");h.each(e,function(s,r){r.apply(p,q)})};if(typeof j.console!="undefined"){if(d(j.console.log.apply)){p.addLogger(function(){j.console.log.apply(j.console,arguments)})}else{p.addLogger(function(){j.console.log(arguments)})}}else{if(typeof console!="undefined"){p.addLogger(function(){console.log.apply(console,arguments)})}}h.extend(p,{makeArray:c,isFunction:d,isArray:m});p.Object=function(q){return h.extend(this,q||{})};h.extend(p.Object.prototype,{escapeHTML:f,h:f,toHash:function(){var q={};h.each(this,function(s,r){if(!d(r)){q[s]=r}});return q},toHTML:function(){var q="";h.each(this,function(s,r){if(!d(r)){q+="<strong>"+s+"</strong> "+r+"<br />"}});return q},keys:function(q){var r=[];for(var s in this){if(!d(this[s])||!q){r.push(s)}}return r},has:function(q){return this[q]&&h.trim(this[q].toString())!==""},join:function(){var r=c(arguments);var q=r.shift();return r.join(q)},log:function(){p.log.apply(p,arguments)},toString:function(q){var r=[];h.each(this,function(t,s){if(!d(s)||q){r.push('"'+t+'": '+s.toString())}});return"Sammy.Object: {"+r.join(",")+"}"}});p.DefaultLocationProxy=function(r,q){this.app=r;this.is_native=false;this.has_history=o;this._startPolling(q)};p.DefaultLocationProxy.fullPath=function(q){var r=q.toString().match(/^[^#]*(#.+)$/);var s=r?r[1]:"";return[q.pathname,q.search,s].join("")};p.DefaultLocationProxy.prototype={bind:function(){var r=this,s=this.app,q=p.DefaultLocationProxy;h(j).bind("hashchange."+this.app.eventNamespace(),function(u,t){if(r.is_native===false&&!t){r.is_native=true;j.clearInterval(q._interval)}s.trigger("location-changed")});if(o&&!s.disable_push_state){h(j).bind("popstate."+this.app.eventNamespace(),function(t){s.trigger("location-changed")});h("a").live("click.history-"+this.app.eventNamespace(),function(u){var t=q.fullPath(this);if(this.hostname==j.location.hostname&&s.lookupRoute("get",t)){u.preventDefault();r.setLocation(t);return false}})}if(!q._bindings){q._bindings=0}q._bindings++},unbind:function(){h(j).unbind("hashchange."+this.app.eventNamespace());h(j).unbind("popstate."+this.app.eventNamespace());h("a").die("click.history-"+this.app.eventNamespace());p.DefaultLocationProxy._bindings--;if(p.DefaultLocationProxy._bindings<=0){j.clearInterval(p.DefaultLocationProxy._interval)}},getLocation:function(){return p.DefaultLocationProxy.fullPath(j.location)},setLocation:function(q){if(/^([^#\/]|$)/.test(q)){if(o){q="/"+q}else{q="#!/"+q}}if(q!=this.getLocation()){if(o&&/^\//.test(q)){history.pushState({path:q},j.title,q);this.app.trigger("location-changed")}else{return(j.location=q)}}},_startPolling:function(s){var r=this;if(!p.DefaultLocationProxy._interval){if(!s){s=10}var q=function(){var t=r.getLocation();if(typeof p.DefaultLocationProxy._last_location=="undefined"||t!=p.DefaultLocationProxy._last_location){j.setTimeout(function(){h(j).trigger("hashchange",[true])},0)}p.DefaultLocationProxy._last_location=t};q();p.DefaultLocationProxy._interval=j.setInterval(q,s)}}};p.Application=function(q){var r=this;this.routes={};this.listeners=new p.Object({});this.arounds=[];this.befores=[];this.namespace=(new Date()).getTime()+"-"+parseInt(Math.random()*1000,10);this.context_prototype=function(){p.EventContext.apply(this,arguments)};this.context_prototype.prototype=new p.EventContext();if(d(q)){q.apply(this,[this])}if(!this._location_proxy){this.setLocationProxy(new p.DefaultLocationProxy(this,this.run_interval_every))}if(this.debug){this.bindToAllEvents(function(t,s){r.log(r.toString(),t.cleaned_type,s||{})})}};p.Application.prototype=h.extend({},p.Object.prototype,{ROUTE_VERBS:["get","post","put","delete"],APP_EVENTS:["run","unload","lookup-route","run-route","route-found","event-context-before","event-context-after","changed","error","check-form-submission","redirect","location-changed"],_last_route:null,_location_proxy:null,_running:false,element_selector:"body",debug:false,raise_errors:false,run_interval_every:50,disable_push_state:false,template_engine:null,toString:function(){return"Sammy.Application:"+this.element_selector},$element:function(q){return q?h(this.element_selector).find(q):h(this.element_selector)},use:function(){var q=c(arguments),s=q.shift(),r=s||"";try{q.unshift(this);if(typeof s=="string"){r="Sammy."+s;s=p[s]}s.apply(this,q)}catch(t){if(typeof s==="undefined"){this.error("Plugin Error: called use() but plugin ("+r.toString()+") is not defined",t)}else{if(!d(s)){this.error("Plugin Error: called use() but '"+r.toString()+"' is not a function",t)}else{this.error("Plugin Error",t)}}}return this},setLocationProxy:function(q){var r=this._location_proxy;this._location_proxy=q;if(this.isRunning()){if(r){r.unbind()}this._location_proxy.bind()}},route:function(u,r,w){var t=this,v=[],q,s;if(!w&&d(r)){r=u;w=r;u="any"}u=u.toLowerCase();if(r.constructor==String){k.lastIndex=0;while((s=k.exec(r))!==null){v.push(s[1])}r=new RegExp(r.replace(k,g)+"$")}if(typeof w=="string"){w=t[w]}q=function(x){var y={verb:x,path:r,callback:w,param_names:v};t.routes[x]=t.routes[x]||[];t.routes[x].push(y)};if(u==="any"){h.each(this.ROUTE_VERBS,function(y,x){q(x)})}else{q(u)}return this},get:n("get"),post:n("post"),put:n("put"),del:n("delete"),any:n("any"),mapRoutes:function(r){var q=this;h.each(r,function(s,t){q.route.apply(q,t)});return this},eventNamespace:function(){return["sammy-app",this.namespace].join("-")},bind:function(q,s,u){var t=this;if(typeof u=="undefined"){u=s}var r=function(){var x,v,w;x=arguments[0];w=arguments[1];if(w&&w.context){v=w.context;delete w.context}else{v=new t.context_prototype(t,"bind",x.type,w,x.target)}x.cleaned_type=x.type.replace(t.eventNamespace(),"");u.apply(v,[x,w])};if(!this.listeners[q]){this.listeners[q]=[]}this.listeners[q].push(r);if(this.isRunning()){this._listen(q,r)}return this},trigger:function(q,r){this.$element().trigger([q,this.eventNamespace()].join("."),[r]);return this},refresh:function(){this.last_location=null;this.trigger("location-changed");return this},before:function(q,r){if(d(q)){r=q;q={}}this.befores.push([q,r]);return this},after:function(q){return this.bind("event-context-after",q)},around:function(q){this.arounds.push(q);return this},isRunning:function(){return this._running},helpers:function(q){h.extend(this.context_prototype.prototype,q);return this},helper:function(q,r){this.context_prototype.prototype[q]=r;return this},run:function(q){if(this.isRunning()){return false}var r=this;h.each(this.listeners.toHash(),function(s,t){h.each(t,function(v,u){r._listen(s,u)})});this.trigger("run",{start_url:q});this._running=true;this.last_location=null;if(!(/\#(.+)/.test(this.getLocation()))&&typeof q!="undefined"){this.setLocation(q)}this._checkLocation();this._location_proxy.bind();this.bind("location-changed",function(){r._checkLocation()});this.bind("submit",function(t){var s=r._checkFormSubmission(h(t.target).closest("form"));return(s===false)?t.preventDefault():false});h(j).bind("beforeunload",function(){r.unload()});return this.trigger("changed")},unload:function(){if(!this.isRunning()){return false}var q=this;this.trigger("unload");this._location_proxy.unbind();this.$element().unbind("submit").removeClass(q.eventNamespace());h.each(this.listeners.toHash(),function(r,s){h.each(s,function(u,t){q._unlisten(r,t)})});this._running=false;return this},bindToAllEvents:function(r){var q=this;h.each(this.APP_EVENTS,function(s,t){q.bind(t,r)});h.each(this.listeners.keys(true),function(t,s){if(h.inArray(s,q.APP_EVENTS)==-1){q.bind(s,r)}});return this},routablePath:function(q){return q.replace(l,"")},lookupRoute:function(w,u){var v=this,t=false,s=0,q,r;if(typeof this.routes[w]!="undefined"){q=this.routes[w].length;for(;s<q;s++){r=this.routes[w][s];if(v.routablePath(u).match(r.path)){t=r;break}}}return t},runRoute:function(s,F,u,x){var t=this,D=this.lookupRoute(s,F),r,A,v,z,E,B,y,C,q;this.log("runRoute",[s,F].join(" "));this.trigger("run-route",{verb:s,path:F,params:u});if(typeof u=="undefined"){u={}}h.extend(u,this._parseQueryString(F));if(D){this.trigger("route-found",{route:D});if((C=D.path.exec(this.routablePath(F)))!==null){C.shift();h.each(C,function(G,H){if(D.param_names[G]){u[D.param_names[G]]=i(H)}else{if(!u.splat){u.splat=[]}u.splat.push(i(H))}})}r=new this.context_prototype(this,s,F,u,x);v=this.arounds.slice(0);E=this.befores.slice(0);y=[r].concat(u.splat);A=function(){var G;while(E.length>0){B=E.shift();if(t.contextMatchesOptions(r,B[0])){G=B[1].apply(r,[r]);if(G===false){return false}}}t.last_route=D;r.trigger("event-context-before",{context:r});G=D.callback.apply(r,y);r.trigger("event-context-after",{context:r});return G};h.each(v.reverse(),function(G,H){var I=A;A=function(){return H.apply(r,[I])}});try{q=A()}catch(w){this.error(["500 Error",s,F].join(" "),w)}return q}else{return this.notFound(s,F)}},contextMatchesOptions:function(t,v,r){var s=v;if(typeof s==="undefined"||s=={}){return true}if(typeof r==="undefined"){r=true}if(typeof s==="string"||d(s.test)){s={path:s}}if(s.only){return this.contextMatchesOptions(t,s.only,true)}else{if(s.except){return this.contextMatchesOptions(t,s.except,false)}}var q=true,u=true;if(s.path){if(!d(s.path.test)){s.path=new RegExp(s.path.toString()+"$")}q=s.path.test(t.path)}if(s.verb){if(typeof s.verb==="string"){u=s.verb===t.verb}else{u=s.verb.indexOf(t.verb)>-1}}return r?(u&&q):!(u&&q)},getLocation:function(){return this._location_proxy.getLocation()},setLocation:function(q){return this._location_proxy.setLocation(q)},swap:function(q){return this.$element().html(q)},templateCache:function(q,r){if(typeof r!="undefined"){return a[q]=r}else{return a[q]}},clearTemplateCache:function(){return a={}},notFound:function(s,r){var q=this.error(["404 Not Found",s,r].join(" "));return(s==="get")?q:true},error:function(r,q){if(!q){q=new Error()}q.message=[r,q.message].join(" ");this.trigger("error",{message:q.message,error:q});if(this.raise_errors){throw (q)}else{this.log(q.message,q)}},_checkLocation:function(){var q,r;q=this.getLocation();if(!this.last_location||this.last_location[0]!="get"||this.last_location[1]!=q){this.last_location=["get",q];r=this.runRoute("get",q)}return r},_getFormVerb:function(s){var r=h(s),t,q;q=r.find('input[name="_method"]');if(q.length>0){t=q.val()}if(!t){t=r[0].getAttribute("method")}if(!t||t==""){t="get"}return h.trim(t.toString().toLowerCase())},_checkFormSubmission:function(s){var q,t,v,u,r;this.trigger("check-form-submission",{form:s});q=h(s);t=q.attr("action")||"";v=this._getFormVerb(q);this.log("_checkFormSubmission",q,t,v);if(v==="get"){this.setLocation(t+"?"+this._serializeFormParams(q));r=false}else{u=h.extend({},this._parseFormParams(q));r=this.runRoute(v,t,u,s.get(0))}return(typeof r=="undefined")?false:r},_serializeFormParams:function(r){var t="",q=r.serializeArray(),s;if(q.length>0){t=this._encodeFormPair(q[0].name,q[0].value);for(s=1;s<q.length;s++){t=t+"&"+this._encodeFormPair(q[s].name,q[s].value)}}return t},_encodeFormPair:function(q,r){return b(q)+"="+b(r)},_parseFormParams:function(q){var t={},s=q.serializeArray(),r;for(r=0;r<s.length;r++){t=this._parseParamPair(t,s[r].name,s[r].value)}return t},_parseQueryString:function(t){var v={},s,r,u,q;s=t.match(l);if(s){r=s[1].split("&");for(q=0;q<r.length;q++){u=r[q].split("=");v=this._parseParamPair(v,i(u[0]),i(u[1]||""))}}return v},_parseParamPair:function(s,q,r){if(s[q]){if(m(s[q])){s[q].push(r)}else{s[q]=[s[q],r]}}else{s[q]=r}return s},_listen:function(q,r){return this.$element().bind([q,this.eventNamespace()].join("."),r)},_unlisten:function(q,r){return this.$element().unbind([q,this.eventNamespace()].join("."),r)}});p.RenderContext=function(q){this.event_context=q;this.callbacks=[];this.previous_content=null;this.content=null;this.next_engine=false;this.waiting=false};p.RenderContext.prototype=h.extend({},p.Object.prototype,{then:function(s){if(!d(s)){if(typeof s==="string"&&s in this.event_context){var r=this.event_context[s];s=function(t){return r.apply(this.event_context,[t])}}else{return this}}var q=this;if(this.waiting){this.callbacks.push(s)}else{this.wait();j.setTimeout(function(){var t=s.apply(q,[q.content,q.previous_content]);if(t!==false){q.next(t)}},0)}return this},wait:function(){this.waiting=true},next:function(q){this.waiting=false;if(typeof q!=="undefined"){this.previous_content=this.content;this.content=q}if(this.callbacks.length>0){this.then(this.callbacks.shift())}},load:function(q,r,t){var s=this;return this.then(function(){var u,v,x,w;if(d(r)){t=r;r={}}else{r=h.extend({},r)}if(t){this.then(t)}if(typeof q==="string"){x=(q.match(/\.json$/)||r.json);u=((x&&r.cache===true)||r.cache!==false);s.next_engine=s.event_context.engineFor(q);delete r.cache;delete r.json;if(r.engine){s.next_engine=r.engine;delete r.engine}if(u&&(v=this.event_context.app.templateCache(q))){return v}this.wait();h.ajax(h.extend({url:q,data:{},dataType:x?"json":null,type:"get",success:function(y){if(u){s.event_context.app.templateCache(q,y)}s.next(y)}},r));return false}else{if(q.nodeType){return q.innerHTML}if(q.selector){s.next_engine=q.attr("data-engine");if(r.clone===false){return q.remove()[0].innerHTML.toString()}else{return q[0].innerHTML.toString()}}}})},loadPartials:function(q){if(q){this.partials=this.partials||{};for(name in q){this.load(q[name]).then(function(r){this.partials[name]=r})}}return this},render:function(q,s,t,r){if(d(q)&&!s){return this.then(q)}else{return this.loadPartials(r).load(q).interpolate(s,q).then(t)}},partial:function(q,r){return this.render(q,r).swap()},send:function(){var s=this,r=c(arguments),q=r.shift();if(m(r[0])){r=r[0]}return this.then(function(t){r.push(function(u){s.next(u)});s.wait();q.apply(q,r);return false})},collect:function(u,t,q){var s=this;var r=function(){if(d(u)){t=u;u=this.content}var v=[],w=false;h.each(u,function(x,z){var y=t.apply(s,[x,z]);if(y.jquery&&y.length==1){y=y[0];w=true}v.push(y);return y});return w?v:v.join("")};return q?r():this.then(r)},renderEach:function(q,r,s,t){if(m(r)){t=s;s=r;r=null}return this.load(q).then(function(v){var u=this;if(!s){s=m(this.previous_content)?this.previous_content:[]}if(t){h.each(s,function(w,y){var z={},x=this.next_engine||q;r?(z[r]=y):(z=y);t(y,u.event_context.interpolate(v,z,x))})}else{return this.collect(s,function(w,y){var z={},x=this.next_engine||q;r?(z[r]=y):(z=y);return this.event_context.interpolate(v,z,x)},true)}})},interpolate:function(t,s,q){var r=this;return this.then(function(v,u){if(!t&&u){t=u}if(this.next_engine){s=this.next_engine;this.next_engine=false}var w=r.event_context.interpolate(v,t,s,this.partials);return q?u+w:w})},swap:function(){return this.then(function(q){this.event_context.swap(q)}).trigger("changed",{})},appendTo:function(q){return this.then(function(r){h(q).append(r)}).trigger("changed",{})},prependTo:function(q){return this.then(function(r){h(q).prepend(r)}).trigger("changed",{})},replace:function(q){return this.then(function(r){h(q).html(r)}).trigger("changed",{})},trigger:function(q,r){return this.then(function(s){if(typeof r=="undefined"){r={content:s}}this.event_context.trigger(q,r)})}});p.EventContext=function(u,t,r,s,q){this.app=u;this.verb=t;this.path=r;this.params=new p.Object(s);this.target=q};p.EventContext.prototype=h.extend({},p.Object.prototype,{$element:function(){return this.app.$element(c(arguments).shift())},engineFor:function(s){var r=this,q;if(d(s)){return s}s=(s||r.app.template_engine).toString();if((q=s.match(/\.([^\.\?\#]+)$/))){s=q[1]}if(s&&d(r[s])){return r[s]}if(r.app.template_engine){return this.engineFor(r.app.template_engine)}return function(t,u){return t}},interpolate:function(s,t,r,q){return this.engineFor(r).apply(this,[s,t,q])},render:function(q,s,t,r){return new p.RenderContext(this).render(q,s,t,r)},renderEach:function(q,r,s,t){return new p.RenderContext(this).renderEach(q,r,s,t)},load:function(q,r,s){return new p.RenderContext(this).load(q,r,s)},partial:function(q,r){return new p.RenderContext(this).partial(q,r)},send:function(){var q=new p.RenderContext(this);return q.send.apply(q,arguments)},redirect:function(){var y,w=c(arguments),v=this.app.getLocation(),r=w.length;if(r>1){var u=0,z=[],q=[],t={},x=false;for(;u<r;u++){if(typeof w[u]=="string"){z.push(w[u])}else{h.extend(t,w[u]);x=true}}y=z.join("/");if(x){for(var s in t){q.push(this.app._encodeFormPair(s,t[s]))}y+="?"+q.join("&")}}else{y=w[0]}this.trigger("redirect",{to:y});this.app.last_location=[this.verb,this.path];this.app.setLocation(y);if(new RegExp(y).test(v)){this.app.trigger("location-changed")}},trigger:function(q,r){if(typeof r=="undefined"){r={}}if(!r.context){r.context=this}return this.app.trigger(q,r)},eventNamespace:function(){return this.app.eventNamespace()},swap:function(q){return this.app.swap(q)},notFound:function(){return this.app.notFound(this.verb,this.path)},json:function(q){return h.parseJSON(q)},toString:function(){return"Sammy.EventContext: "+[this.verb,this.path,this.params].join(" ")}});h.sammy=j.Sammy=p})(jQuery,window);
|
@@ -0,0 +1,5 @@
|
|
1
|
+
// -- Sammy.js -- /plugins/sammy.handlebars.js
|
2
|
+
// http://sammyjs.org
|
3
|
+
// Version: 0.7.0
|
4
|
+
// Built: 2011-07-30 16:55:44 -0700
|
5
|
+
(function(a){Sammy=Sammy||{};Sammy.Handlebars=function(e,c){var d={};var b=function(i,j,g,f){if(typeof f=="undefined"){f=i}var h=d[f];if(!h){h=d[f]=Handlebars.compile(i)}j=a.extend({},this,j);g=a.extend({},j.partials,g);return h(j,{partials:g})};if(!c){c="handlebars"}e.helper(c,b)}})(jQuery);
|
@@ -0,0 +1,5 @@
|
|
1
|
+
// -- Sammy.js -- /plugins/sammy.template.js
|
2
|
+
// http://sammyjs.org
|
3
|
+
// Version: 0.7.0
|
4
|
+
// Built: 2011-07-30 16:55:51 -0700
|
5
|
+
(function(c){var a={};var b=function(e,g,h,d){var f,i;if(a[e]){f=a[e]}else{if(typeof g=="undefined"){return false}if(d&&d.escape_html===false){i='",$1,"'}else{i='",h($1),"'}f=a[e]=new Function("obj",'var ___$$$___=[],print=function(){___$$$___.push.apply(___$$$___,arguments);};with(obj){___$$$___.push("'+String(g).replace(/[\r\t\n]/g," ").replace(/\"/g,'\\"').split("<%").join("\t").replace(/((^|%>)[^\t]*)/g,"$1\r").replace(/\t=(.*?)%>/g,i).replace(/\t!(.*?)%>/g,'",$1,"').split("\t").join('");').split("%>").join('___$$$___.push("').split("\r").join("")+"\");}return ___$$$___.join('');")}if(typeof h!="undefined"){return f(h)}else{return f}};Sammy=Sammy||{};Sammy.Template=function(f,d){var e=function(i,j,h,g){if(typeof h=="undefined"){h=i}if(typeof g=="undefined"&&typeof h=="object"){g=h;h=i}return b(h,i,c.extend({},this,j),g)};if(!d){d="template"}f.helper(d,e)}})(jQuery);
|
@@ -0,0 +1 @@
|
|
1
|
+
<h3 id=no-result-{{sourceId}} class="no-results-title">No results for {{name}}</h3>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h3 id="oembed-failed" class="oembed-failed-title">Unable to load oEmbed for {{oembed_url}}</h3>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<div id="result-description-and-sizes">
|
2
|
+
|
3
|
+
<h2 class="result-title">Title: {{result_title}}</h2>
|
4
|
+
<h2 class="result-author">by <a href="{{result_author_url}}" target="_blank">{{result_author_name}}</a></h2>
|
5
|
+
|
6
|
+
<h1 class="result-size-choice-headline">Choose a size</h1>
|
7
|
+
|
8
|
+
<ul id="result-sizes">
|
9
|
+
{{#sizes}}
|
10
|
+
<li class="size-choice" id=result-sizes-{{size_name}}>
|
11
|
+
<a href=#/selections/{{oembed_url}} class="result-size-choose"><img src="{{url}}" width="{{width}}" height="{{height}}" class="result-size-image"></a>
|
12
|
+
<div class="size-name"><a href=#/selections/{{oembed_url}} class="result-size-choose">{{size_name}}</a></div>
|
13
|
+
</li>
|
14
|
+
{{/sizes}}
|
15
|
+
</ul>
|
16
|
+
|
17
|
+
<div id="home-link"><a href="index.html">Back to Sources</a></div>
|
18
|
+
</div>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<li class="result-grid">
|
2
|
+
<h4 class="result-thumbnail-title">{{title}} [<a href="{{link}}" target="_blank">view original</a>]</h4>
|
3
|
+
<a class="result-thumbnail" href=#/results/{{link_escaped}}><img src="{{thumbnail_url}}" class="result-thumbnail"></a>
|
4
|
+
<div class="result-thumbnail-select">Select</a></div>
|
5
|
+
</li>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h3 id=results-failed-{{sourceId}} class="results-failed-title">Results from {{name}} failed to load.</h3>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<h1 class="selection-headline">Your selection</h1>
|
2
|
+
|
3
|
+
<h2 class="selection-title">Title: {{title}}</h2>
|
4
|
+
<h2 class="selection-author">by <a href="{{author_url}}" target="_blank">{{author_name}}</a></h2>
|
5
|
+
|
6
|
+
<img src="{{url}}" width="{{width}}" height="{{height}}" class="selection-image">
|
7
|
+
|
8
|
+
<div id="embed-details">
|
9
|
+
<h3>Embed:</h3>
|
10
|
+
|
11
|
+
<textarea class="selection-embed"><img src="{{url}}" width="{{width}}" height="{{height}}" alt="{{alt}}"> by <a href="{{author_url}}">{{author_name}}</a></textarea>
|
12
|
+
|
13
|
+
</div>
|
14
|
+
<div id="home-link"><a href="index.html">Back to Sources</a></div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h3 id="sizes-failed" class="sizes-failed-title">Unable to load sizes settings.</h3>
|
@@ -0,0 +1 @@
|
|
1
|
+
<li class="source" id={{sourceId}}><a href=#/{{sourceId}}>{{name}}</a></li>
|
@@ -0,0 +1 @@
|
|
1
|
+
<div id="next-page"><a href=#/{{sourceId}}/page/{{nextPage}}>More results >></a></div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<li class="source source-selected" id={{sourceId}}>{{name}}</li>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<li class="source source-selected" id={{sourceId}}>
|
2
|
+
<div class="source-search-form">
|
3
|
+
<form action="#/{{sourceId}}" method="post">
|
4
|
+
<label>{{name}}:</label>
|
5
|
+
<input type="text" size="15" name="search_terms" value="{{value}}" />
|
6
|
+
<input type="submit" value="Update" />
|
7
|
+
</form>
|
8
|
+
</div>
|
9
|
+
</li>
|
@@ -0,0 +1 @@
|
|
1
|
+
<li class="upload-link"><a href="{{url}}{{service_target_param}}">{{label}}</li>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Make sure the tiny_mce gem has been loaded before we declare any plugins
|
2
|
+
require 'tiny_mce'
|
3
|
+
|
4
|
+
# We need to make sure that the TinyMCE Editor sources are already in place
|
5
|
+
# or any changes we make may be overwritten later, this will return if TinyMCE already initialized
|
6
|
+
TinyMCE.initialize
|
7
|
+
|
8
|
+
# Create the TinyMCE Imageselector Plugin. Inherit from TinyMCE::Plugin which sets a
|
9
|
+
# default self.install method, which installs all files in self.assets_path
|
10
|
+
# into the public/javascripts/tiny_mce directory
|
11
|
+
class TinyMCEImageselector < TinyMCE::Plugin
|
12
|
+
|
13
|
+
# This lets the TinyMCE::Plugin classes install method know where to find
|
14
|
+
# the assets we need to install. If were overwrite the self.install method
|
15
|
+
# here, then we don't need to provide this line
|
16
|
+
self.assets_path = File.join(File.dirname(__FILE__), 'assets')
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
# Finally, tell the TinyMCEImageselector Plugin to install itself. The install method
|
21
|
+
# can be overwritten in the class definition above. TinyMCE::Plugin provide a
|
22
|
+
# default one that will work fine in this example
|
23
|
+
TinyMCEImageselector.install
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "tiny_mce_plugin_imageselector"
|
3
|
+
s.version = "0.0.2"
|
4
|
+
s.authors = ["Walter McGinnis"]
|
5
|
+
s.email = "walter@katipo.co.nz"
|
6
|
+
s.homepage = "http://github.com/kete/tiny_mce_plugin_imageselector"
|
7
|
+
s.summary = "A gem to install the imageselector tiny_mce plugin in tandem with the tinymce gem."
|
8
|
+
s.description = "This gem uses the tiny_mce gem's plugin system to install the https://github.com/kete/image_selector_tinymce_plugin plugin."
|
9
|
+
|
10
|
+
s.files = Dir["lib/**/*", "[A-Z]*", "tiny_mce_plugin_imageselector.gemspec"]
|
11
|
+
s.require_path = "lib"
|
12
|
+
|
13
|
+
s.extra_rdoc_files = Dir["*.rdoc"]
|
14
|
+
s.rdoc_options = ["--charset=UTF-8", "--exclude=lib/assets"]
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tiny_mce_plugin_imageselector
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Walter McGinnis
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-09-23 00:00:00 +12:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: This gem uses the tiny_mce gem's plugin system to install the https://github.com/kete/image_selector_tinymce_plugin plugin.
|
23
|
+
email: walter@katipo.co.nz
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README.rdoc
|
30
|
+
files:
|
31
|
+
- lib/assets/plugins/imageselector/css/media_selector.css
|
32
|
+
- lib/assets/plugins/imageselector/dialog.htm
|
33
|
+
- lib/assets/plugins/imageselector/editor_plugin.js
|
34
|
+
- lib/assets/plugins/imageselector/editor_plugin_src.js
|
35
|
+
- lib/assets/plugins/imageselector/img/example.gif
|
36
|
+
- lib/assets/plugins/imageselector/img/imageselector.png
|
37
|
+
- lib/assets/plugins/imageselector/img/spinner.gif
|
38
|
+
- lib/assets/plugins/imageselector/js/media_selector.js
|
39
|
+
- lib/assets/plugins/imageselector/js/sammy-0.7.0.min.js
|
40
|
+
- lib/assets/plugins/imageselector/js/sammy.handlebars-0.7.0.min.js
|
41
|
+
- lib/assets/plugins/imageselector/js/sammy.template-0.7.0.min.js
|
42
|
+
- lib/assets/plugins/imageselector/langs/en.js
|
43
|
+
- lib/assets/plugins/imageselector/langs/en_dlg.js
|
44
|
+
- lib/assets/plugins/imageselector/LICENSE
|
45
|
+
- lib/assets/plugins/imageselector/README.md
|
46
|
+
- lib/assets/plugins/imageselector/templates/no_results.hb
|
47
|
+
- lib/assets/plugins/imageselector/templates/oembed_failed.rb
|
48
|
+
- lib/assets/plugins/imageselector/templates/result.hb
|
49
|
+
- lib/assets/plugins/imageselector/templates/result_thumbnail.hb
|
50
|
+
- lib/assets/plugins/imageselector/templates/results_failed.hb
|
51
|
+
- lib/assets/plugins/imageselector/templates/selection.hb
|
52
|
+
- lib/assets/plugins/imageselector/templates/sizes_failed.rb
|
53
|
+
- lib/assets/plugins/imageselector/templates/source.hb
|
54
|
+
- lib/assets/plugins/imageselector/templates/source_next_page_link.hb
|
55
|
+
- lib/assets/plugins/imageselector/templates/source_next_page_link_search.hb
|
56
|
+
- lib/assets/plugins/imageselector/templates/source_search.hb
|
57
|
+
- lib/assets/plugins/imageselector/templates/source_selected.hb
|
58
|
+
- lib/assets/plugins/imageselector/templates/source_selected_search.hb
|
59
|
+
- lib/assets/plugins/imageselector/templates/upload.hb
|
60
|
+
- lib/tiny_mce_plugin_imageselector.rb
|
61
|
+
- LICENSE
|
62
|
+
- README.rdoc
|
63
|
+
- tiny_mce_plugin_imageselector.gemspec
|
64
|
+
has_rdoc: true
|
65
|
+
homepage: http://github.com/kete/tiny_mce_plugin_imageselector
|
66
|
+
licenses: []
|
67
|
+
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options:
|
70
|
+
- --charset=UTF-8
|
71
|
+
- --exclude=lib/assets
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 3
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
hash: 3
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
requirements: []
|
93
|
+
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 1.3.7
|
96
|
+
signing_key:
|
97
|
+
specification_version: 3
|
98
|
+
summary: A gem to install the imageselector tiny_mce plugin in tandem with the tinymce gem.
|
99
|
+
test_files: []
|
100
|
+
|