tiny_mce_plugin_imageselector 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|