diff options
22 files changed, 490 insertions, 106 deletions
diff --git a/etherpad/etc/etherpad.localdev-default.properties b/etherpad/etc/etherpad.localdev-default.properties index c2a2122..26bc8e5 100644 --- a/etherpad/etc/etherpad.localdev-default.properties +++ b/etherpad/etc/etherpad.localdev-default.properties @@ -14,3 +14,4 @@ modulePath = ./src transportPrefix = /comet transportUseWildcardSubdomains = true useVirtualFileRoot = ./src +motdPage = /ep/pad/view/ro.3PfHCD0ApLc/latest?fullScreen=1&slider=0&sidebar=0
\ No newline at end of file diff --git a/etherpad/src/etherpad/admin/plugins.js b/etherpad/src/etherpad/admin/plugins.js index 6fc21f3..7b59662 100644 --- a/etherpad/src/etherpad/admin/plugins.js +++ b/etherpad/src/etherpad/admin/plugins.js @@ -195,7 +195,6 @@ function enablePlugin(pluginName) { saveInstalledHooks(pluginName); throw e; } - log.info({PLUGINS:plugins, HOOKS:hooks}); } function disablePlugin(pluginName) { @@ -207,7 +206,6 @@ function disablePlugin(pluginName) { } unloadPluginHooks(pluginName); saveInstalledHooks(pluginName); - log.info({PLUGINS:plugins, HOOKS:hooks}); } function registerClientHandlerJS() { diff --git a/etherpad/src/etherpad/control/admin/pluginmanager.js b/etherpad/src/etherpad/control/admin/pluginmanager.js index e293592..39edc4a 100644 --- a/etherpad/src/etherpad/control/admin/pluginmanager.js +++ b/etherpad/src/etherpad/control/admin/pluginmanager.js @@ -54,8 +54,6 @@ function onRequest() { renderHtml("admin/pluginmanager.ejs", { - pluginModules: plugins.pluginModules, - plugins: plugins.plugins, config: appjet.config, bodyClass: 'nonpropad', isPro: pro_utils.isProDomainRequest(), diff --git a/etherpad/src/etherpad/db_migrations/m0040_create_plugin_tables.js b/etherpad/src/etherpad/db_migrations/m0040_create_plugin_tables.js new file mode 100644 index 0000000..62e8ff7 --- /dev/null +++ b/etherpad/src/etherpad/db_migrations/m0040_create_plugin_tables.js @@ -0,0 +1,40 @@ +/** + * Copyright 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS-IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import("etherpad.utils.isPrivateNetworkEdition"); +import("sqlbase.sqlobj"); +import("sqlbase.sqlcommon"); + +function run() { + sqlobj.createTable('plugin', { + id: 'INT NOT NULL '+sqlcommon.autoIncrementClause()+' PRIMARY KEY', + name: 'VARCHAR(128) character set utf8 collate utf8_bin UNIQUE NOT NULL' + }); + sqlobj.createTable('hook_type', { + id: 'INT NOT NULL '+sqlcommon.autoIncrementClause()+' PRIMARY KEY', + name: 'VARCHAR(128) character set utf8 collate utf8_bin UNIQUE NOT NULL' + }); + sqlobj.createTable('hook', { + id: 'INT NOT NULL '+sqlcommon.autoIncrementClause()+' PRIMARY KEY', + type_id: 'INT NOT NULL REFERENCES hook_type(id)', + name: 'VARCHAR(128) character set utf8 collate utf8_bin NOT NULL' + }); + sqlobj.createTable('plugin_hook', { + plugin_id: 'INT NOT NULL REFERENCES plugin(id)', + hook_id: 'INT NOT NULL REFERENCES hook(id)', + original_name: 'VARCHAR(128) character set utf8 collate utf8_bin' + }); +} diff --git a/etherpad/src/etherpad/db_migrations/migration_runner.js b/etherpad/src/etherpad/db_migrations/migration_runner.js index ddf201d..f4fa861 100644 --- a/etherpad/src/etherpad/db_migrations/migration_runner.js +++ b/etherpad/src/etherpad/db_migrations/migration_runner.js @@ -69,7 +69,8 @@ var migrations = [ "m0035_add_email_to_paymentinfo", "m0036_create_missing_subscription_records", "m0037_create_pro_referral_table", - "m0038_pad_coarse_revs" + "m0038_pad_coarse_revs", + "m0040_create_plugin_tables" ]; var mscope = this; diff --git a/etherpad/src/etherpad/globals.js b/etherpad/src/etherpad/globals.js index 3475b88..343a989 100644 --- a/etherpad/src/etherpad/globals.js +++ b/etherpad/src/etherpad/globals.js @@ -20,7 +20,7 @@ var COMETPATH = "/comet"; -var COLOR_PALETTE = ['#ffc6c6','#ffe2bf','#fffcbf','#cbffb3','#b3fff1','#c6e7ff','#dcccff','#ffd9fb']; +var COLOR_PALETTE = ['#ffc7c7','#fff1c7','#e3ffc7','#c7ffd5','#c7ffff','#c7d5ff','#e3c7ff','#ffc7f1','#ff8f8f','#ffe38f','#c7ff8f','#8fffab','#8fffff','#8fabff','#c78fff','#ff8fe3','#d97979','#d9c179','#a9d979','#79d991','#79d9d9','#7991d9','#a979d9','#d979c1','#d9a9a9','#d9cda9','#c1d9a9','#a9d9b5','#a9d9d9','#a9b5d9','#c1a9d9','#d9a9cd']; function isProduction() { return (appjet.config['etherpad.isProduction'] == "true"); diff --git a/etherpad/src/etherpad/utils.js b/etherpad/src/etherpad/utils.js index e60c08a..398090c 100644 --- a/etherpad/src/etherpad/utils.js +++ b/etherpad/src/etherpad/utils.js @@ -67,6 +67,7 @@ function findTemplate(filename, plugin) { function renderTemplateAsString(filename, data, plugin) { data = data || {}; data.helpers = helpers; // global helpers + data.plugins = plugins; // Access callHook and the like... var f = findTemplate(filename, plugin); //"/templates/"+filename; if (! appjet.scopeCache.ejs) { diff --git a/etherpad/src/main.js b/etherpad/src/main.js index 8b08abb..745f5fa 100644 --- a/etherpad/src/main.js +++ b/etherpad/src/main.js @@ -364,19 +364,20 @@ function handlePath() { // these paths are handled identically on all sites/subdomains. var commonDispatcher = new Dispatcher(); - commonDispatcher.addLocations([ - ['/favicon.ico', forward(static_control)], - ['/robots.txt', forward(static_control)], - ['/crossdomain.xml', forward(static_control)], - [PrefixMatcher('/static/'), forward(static_control)], - [PrefixMatcher('/ep/genimg/'), genimg.renderPath], - [PrefixMatcher('/ep/pad/'), forward(pad_control)], - [PrefixMatcher('/ep/script/'), forward(scriptcontrol)], - [/^\/([^\/]+)$/, pad_control.render_pad], - [DirMatcher('/ep/unit-tests/'), forward(testcontrol)], - [DirMatcher('/ep/pne-manual/'), forward(pne_manual_control)], - [DirMatcher('/ep/pro-help/'), forward(pro_help_control)] - ].concat(plugins.callHook('handlePath'))); + commonDispatcher.addLocations( + plugins.callHook('handlePath').concat([ + ['/favicon.ico', forward(static_control)], + ['/robots.txt', forward(static_control)], + ['/crossdomain.xml', forward(static_control)], + [PrefixMatcher('/static/'), forward(static_control)], + [PrefixMatcher('/ep/genimg/'), genimg.renderPath], + [PrefixMatcher('/ep/pad/'), forward(pad_control)], + [PrefixMatcher('/ep/script/'), forward(scriptcontrol)], + [/^\/([^\/]+)$/, pad_control.render_pad], + [DirMatcher('/ep/unit-tests/'), forward(testcontrol)], + [DirMatcher('/ep/pne-manual/'), forward(pne_manual_control)], + [DirMatcher('/ep/pro-help/'), forward(pro_help_control)] + ])); var etherpadDotComDispatcher = new Dispatcher(); etherpadDotComDispatcher.addLocations([ diff --git a/etherpad/src/plugins/twitterStyleTags/controllers/tagBrowser.js b/etherpad/src/plugins/twitterStyleTags/controllers/tagBrowser.js index f5e63f7..461f30a 100644 --- a/etherpad/src/plugins/twitterStyleTags/controllers/tagBrowser.js +++ b/etherpad/src/plugins/twitterStyleTags/controllers/tagBrowser.js @@ -196,12 +196,22 @@ function onRequest() { var newTags = sqlobj.executeRaw(queryNewTagsSql.sql, queryNewTagsSql.params); var matchingPads; - if (tags.length > 0 || antiTags.length > 0) { - var sql = "select p.PAD_ID as ID, p.TAGS from PAD_TAG_CACHE as p, " + querySql.sql + " as q where p.PAD_ID = q.ID limit 10" + var sql = '' + + 'select ' + + ' m.id as ID, ' + + ' DATE_FORMAT(m.lastWriteTime, \'%a, %d %b %Y %H:%i:%s GMT\') as lastWriteTime, ' + + ' c.TAGS ' + + 'from ' + + querySql.sql + ' as q ' + + ' join PAD_SQLMETA as m on ' + + ' m.id = q.ID ' + + ' join PAD_TAG_CACHE as c on ' + + ' c.PAD_ID = q.ID ' + + 'order by ' + + ' m.lastWriteTime desc ' + + 'limit 10'; + matchingPads = sqlobj.executeRaw(sql, querySql.params); - } else { - matchingPads = []; - } for (i = 0; i < matchingPads.length; i++) { matchingPads[i].TAGS = matchingPads[i].TAGS.split('#'); @@ -223,8 +233,7 @@ function onRequest() { var isProUser = (isPro && ! padusers.isGuest(userId)); - renderHtml("tagBrowser.ejs", - { + var info = { config: appjet.config, tagsToQuery: tagsToQuery, padIdToReadonly: server_utils.padIdToReadonly, @@ -236,6 +245,20 @@ function onRequest() { isPro: isPro, isProAccountHolder: isProUser, account: getSessionProAccount(), // may be falsy - }, 'twitterStyleTags'); + }; + + var format = "html"; + if (request.params.format != undefined) + format = request.params.format; + + if (format == "html") + renderHtml("tagBrowser.ejs", info, 'twitterStyleTags'); + else if (format == "rss") { + response.setContentType("application/xml; charset=utf-8"); + response.write(renderTemplateAsString("tagRss.ejs", info, 'twitterStyleTags')); + if (request.acceptsGzip) { + response.setGzip(true); + } + } return true; } diff --git a/etherpad/src/plugins/twitterStyleTags/hooks.js b/etherpad/src/plugins/twitterStyleTags/hooks.js index a5513f0..003bc32 100644 --- a/etherpad/src/plugins/twitterStyleTags/hooks.js +++ b/etherpad/src/plugins/twitterStyleTags/hooks.js @@ -10,7 +10,7 @@ function handlePath() { function padModelWriteToDB(args) { /* Update tags for the pad */ - var new_tags = args.pad.text().match(new RegExp("#[^,#!\\s][^,#!\\s]*", "g")); + var new_tags = args.pad.text().match(new RegExp("#[^,#=!\\s][^,#=!\\s]*", "g")); if (new_tags == null) new_tags = new Array(); for (i = 0; i < new_tags.length; i++) new_tags[i] = new_tags[i].substring(1); diff --git a/etherpad/src/plugins/twitterStyleTags/static/css/pad.css b/etherpad/src/plugins/twitterStyleTags/static/css/pad.css new file mode 100644 index 0000000..e144de5 --- /dev/null +++ b/etherpad/src/plugins/twitterStyleTags/static/css/pad.css @@ -0,0 +1,70 @@ +.padtag a, +.padtag a:visited, +a.padtag, +a.padtag:visited, +a.anti_padtag, +a.anti_padtag:visited { + text-decoration: none !important; + color: #2e2eaa !important; + + border-style: solid; + border-width: 1px; + + border-left-color: #8c8c8c; + border-right-color: #707070; + border-top-color: #9c9c9c; + border-bottom-color: #606060; + + -moz-border-radius-topleft: 3pt; + -moz-border-radius-topright: 3pt; + -moz-border-radius-bottomleft: 3pt; + -moz-border-radius-bottomright: 3pt; + -webkit-border-top-left-radius: 3pt; + -webkit-border-top-right-radius: 3pt; + -webkit-border-bottom-left-radius: 3pt; + -webkit-border-bottom-right-radius: 3pt; + + padding-left: 2pt; + padding-right: 2pt +} + +a.anti_padtag, +a.anti_padtag:visited { + color: #aa2e2e !important; + border-left-color: #aa8c8c; + border-right-color: #aa7070; + border-top-color: #aa9c9c; + border-bottom-color: #aa6060; +} + +.padtag_public a, +.padtag_public a:visited, +a.padtag_public, +a.padtag_public:visited { + color: #2e772e !important; + background-color: #99ff99 !important; + + border-style: solid; + border-width: 1px; + + border-left-color: #8caa8c; + border-right-color: #70aa70; + border-top-color: #9caa9c; + border-bottom-color: #60aa60; +} + +.padtag_writable a, +.padtag_writable a:visited, +a.padtag_writable, +a.padtag_writable:visited { + color: #2e2e77 !important; + background-color: #9999ff !important; + + border-style: solid; + border-width: 1px; + + border-left-color: #8c8caa; + border-right-color: #7070aa; + border-top-color: #9c9caa; + border-bottom-color: #6060aa; +} diff --git a/etherpad/src/plugins/twitterStyleTags/static/css/tagBrowser.css b/etherpad/src/plugins/twitterStyleTags/static/css/tagBrowser.css new file mode 100644 index 0000000..94b2be8 --- /dev/null +++ b/etherpad/src/plugins/twitterStyleTags/static/css/tagBrowser.css @@ -0,0 +1,90 @@ +.padtag a, +.padtag a:visited, +a.padtag, +a.padtag:visited, +a.anti_padtag, +a.anti_padtag:visited { + line-height: 1.7em; +} + +dt { + padding-bottom: 2pt; +} + +dd { + padding-left: 20pt; + padding-bottom: 10pt; +} + +h1 { + font-size: 12pt; + margin-top: 5pt; +} + +.label { + font-size: 14pt; +} + +#editorcontainer { + padding: 5pt; +} + +#editorcontainerbox { + overflow: auto; + height: auto; +} + + +.query-refiner { + float: right; + padding: 10pt; + margin-left: 5pt; + margin-bottom: 5pt; + border: 1px solid #9C9C9C; + width: 40%; +} + +.query-refiner h1 { + margin-bottom: 2pt; + margin-top: 0; +} + +#home-newpad { + display: block; + background-color: #a3bde0; + color: #555555; + border-style: solid; + border-width: 2px; + border-left-color: #d6e2f1; + border-right-color: #86aee1; + border-top-color: #d6e2f1; + border-bottom-color: #86aee1; + margin: 10pt; + text-align: center; + text-decoration: none; + padding-top: 50pt; + padding-bottom: 50pt; + font-size: 20pt; + -moz-border-radius-topleft: 3pt; + -moz-border-radius-topright: 3pt; + -moz-border-radius-bottomleft: 3pt; + -moz-border-radius-bottomright: 3pt; + -webkit-border-top-left-radius: 3pt; + -webkit-border-top-right-radius: 3pt; + -webkit-border-bottom-left-radius: 3pt; + -webkit-border-bottom-right-radius: 3pt; +} + +#editbarinner { + line-height: 36px; + font-size: 16px; + padding-left: 6pt; +} + +#editbarinner a { + font-size: 12px; +} + +#padchat iframe { + border: none; +} diff --git a/etherpad/src/plugins/twitterStyleTags/static/js/main.js b/etherpad/src/plugins/twitterStyleTags/static/js/main.js index eae0c4f..a83e3e8 100644 --- a/etherpad/src/plugins/twitterStyleTags/static/js/main.js +++ b/etherpad/src/plugins/twitterStyleTags/static/js/main.js @@ -1,28 +1,47 @@ function init() { - this.hooks = ['aceGetFilterStack', 'aceCreateDomLine']; + this.hooks = ['aceInitInnerdocbodyHead', 'aceGetFilterStack', 'aceCreateDomLine']; + this.aceInitInnerdocbodyHead = aceInitInnerdocbodyHead; this.aceGetFilterStack = aceGetFilterStack; this.aceCreateDomLine = aceCreateDomLine; } +function aceInitInnerdocbodyHead(args) { + args.iframeHTML.push('\'<link rel="stylesheet" type="text/css" href="/static/css/plugins/twitterStyleTags/pad.css"/>\''); +} + function aceGetFilterStack(args) { - return [args.linestylefilter.getRegexpFilter( - new RegExp("#[^,#!\\s][^,#!\\s]*", "g"), 'padtag')]; + return [ + args.linestylefilter.getRegexpFilter( + new RegExp("#[^,#=!\\s][^,#=!\\s]*", "g"), 'padtag'), + args.linestylefilter.getRegexpFilter( + new RegExp("=[^#=\\s][^#=\\s]*", "g"), 'padtagsearch') + ]; } function aceCreateDomLine(args) { - if (args.cls.indexOf('padtag') < 0) - return; + if (args.cls.indexOf('padtagsearch') >= 0) { + var href; + cls = args.cls.replace(/(^| )padtagsearch:(\S+)/g, function(x0, space, padtagsearch) { + href = '/ep/tag/?query=' + padtagsearch.substring(1); + return space + "padtagsearch padtagsearch_" + padtagsearch.substring(1); + }); - var href; - cls = args.cls.replace(/(^| )padtag:(\S+)/g, function(x0, space, padtag) { - href = '/ep/tag/?query=' + padtag.substring(1); - return space + "padtag padtag_" + padtag.substring(1); - }); + return [{ + cls: cls, + extraOpenTags: '<a href="' + href.replace(/\"/g, '"') + '">', + extraCloseTags: '</a>'}]; + } else if (args.cls.indexOf('padtag') >= 0) { + var href; + cls = args.cls.replace(/(^| )padtag:(\S+)/g, function(x0, space, padtag) { + href = '/ep/tag/?query=' + padtag.substring(1); + return space + "padtag padtag_" + padtag.substring(1); + }); - return [{ - cls: cls, - extraOpenTags: '<a href="' + href.replace(/\"/g, '"') + '">', - extraCloseTags: '</a>'}]; + return [{ + cls: cls, + extraOpenTags: '<a href="' + href.replace(/\"/g, '"') + '">', + extraCloseTags: '</a>'}]; + } } /* used on the client side only */ diff --git a/etherpad/src/plugins/twitterStyleTags/templates/tagBrowser.ejs b/etherpad/src/plugins/twitterStyleTags/templates/tagBrowser.ejs index ba00aa2..1f1c0e3 100644 --- a/etherpad/src/plugins/twitterStyleTags/templates/tagBrowser.ejs +++ b/etherpad/src/plugins/twitterStyleTags/templates/tagBrowser.ejs @@ -12,15 +12,35 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ %> <% - helpers.setHtmlTitle("Browse tags"); + helpers.setHtmlTitle("EtherPad: Browse tags"); + helpers.includeCss("plugins/twitterStyleTags/tagBrowser.css"); + helpers.includeCss("plugins/twitterStyleTags/pad.css"); helpers.setBodyId("padbody"); helpers.addBodyClass("limwidth nonpropad nonprouser"); helpers.includeCss("pad2_ejs.css"); - helpers.setRobotsPolicy({index: false, follow: false}) - helpers.includeJQuery(); + helpers.includeJs("undo-xpopup.js"); helpers.includeCometJs(); + helpers.includeJQuery(); helpers.includeJs("json2.js"); - helpers.addToHead('\n<style type="text/css" title="dynamicsyntax"></style>\n'); + helpers.includeJs("colorutils.js"); + helpers.includeJs("ace.js"); + helpers.includeJs("collab_client.js"); + helpers.includeJs("draggable.js"); + helpers.includeJs("pad_utils.js"); + helpers.includeJs("pad_cookie.js"); + helpers.includeJs("pad_editor.js"); + helpers.includeJs("pad_userlist.js"); + helpers.includeJs("pad_editbar.js"); + helpers.includeJs("pad_chat.js"); + helpers.includeJs("pad_docbar.js"); + helpers.includeJs("pad_impexp.js"); + helpers.includeJs("pad_savedrevs.js"); + helpers.includeJs("pad_connectionstatus.js"); + helpers.includeJs("pad_modals.js"); + helpers.includeJs("pad2.js"); + helpers.suppressGA(); + helpers.setRobotsPolicy({index: false, follow: false}); + helpers.addToHead('\n<link rel="alternate" href="/ep/tag/?query=' + tagsToQuery(tags, antiTags) + '&format=rss" type="application/rss+xml" title="Query results as RSS" />\n'); function inArray(item, arr) { for (var i = 0; i < arr.length; i++) @@ -34,14 +54,13 @@ limitations under the License. */ %> <div id="padtop"> <div id="topbar" style="margin: 7px; margin-top: 0px;"> <div id="topbarleft"><!-- --></div> - <div id="topbarright"><!-- --></div> - <div id="topbarcenter"><a href="/" id="topbaretherpad">EtherPad</a></div> - <% if (isProAccountHolder) { %> - <div id="accountnav"><%= toHTML(account.email) %><a href="/ep/account/sign-out">(sign out)</a></div> - <% } else if (isPro) { %> - <div id="accountnav"><a href="<%= signinUrl %>">sign in</a></div> - <% } %> - </div> + <div id="topbarright"><!-- --></div> + <div id="topbarcenter"><a href="/" id="topbaretherpad">EtherPad</a></div> + <% if (isProAccountHolder) { %> + <div id="accountnav"><%= toHTML(account.email) %><a href="/ep/account/sign-out">(sign out)</a></div> + <% } else if (isPro) { %> + <div id="accountnav"><a href="<%= signinUrl %>">sign in</a></div> + <% } %> </div> <div id="docbar" class="docbar-public"> <div id="docbarleft"><!-- --></div> @@ -74,44 +93,33 @@ limitations under the License. */ %> <div id="editbarright"><!-- --></div> <div id="editbarinner"> - <a unselectable="on" href="javascript:void (window.pad&&pad.editbarClick('bold'));" class="editbarbutton bold" title="Bold (ctrl-B)"> </a> - <a unselectable="on" href="javascript:void (window.pad&&pad.editbarClick('italic'));" class="editbarbutton italic" title="Italics (ctrl-I)"> </a> - <a unselectable="on" href="javascript:void (window.pad&&pad.editbarClick('underline'));" class="editbarbutton underline" title="Underline (ctrl-U)"> </a> - <a unselectable="on" href="javascript:void (window.pad&&pad.editbarClick('strikethrough'));" class="editbarbutton strikethrough" title="Strikethrough"> </a> - <a unselectable="on" href="javascript:void (window.pad&&pad.editbarClick('clearauthorship'));" class="editbarbutton clearauthorship" title="Clear Authorship Colors"> </a> - <a unselectable="on" href="javascript:void (window.pad&&pad.editbarClick('undo'));" class="editbarbutton undo" title="Undo (ctrl-Z)"> </a> - <a unselectable="on" href="javascript:void (window.pad&&pad.editbarClick('redo'));" class="editbarbutton redo" title="Redo (ctrl-Y)"> </a> - <a unselectable="on" href="javascript:void (window.pad&&pad.editbarClick('insertunorderedlist'));" class="editbarbutton insertunorderedlist" title="Toggle Bullet List"> </a> - <a unselectable="on" href="javascript:void (window.pad&&pad.editbarClick('indent'));" class="editbarbutton indent" title="Indent List"> </a> - <a unselectable="on" href="javascript:void (window.pad&&pad.editbarClick('outdent'));" class="editbarbutton outdent" title="Unindent List"> </a> - <a unselectable="on" href="javascript:void (window.pad&&pad.editbarClick('save'));" class="editbarbutton save" title="Save Revision"> </a> + Query: + <% if (tags.length == 0 && antiTags.length == 0) { %> + Latest changed pads + <% } else { %> + <% for (i = 0; i < tags.length; i++) { %> + <a href="/ep/tag/?query=<%= tagsToQuery(tags.filter(function (tag) { return tag != tags[i]}), antiTags) %>" class="padtag" title="<%= tags[i] %> matches">#<%= tags[i] %></a> + <% } %> + <% for (i = 0; i < antiTags.length; i++) { %> + <a href="/ep/tag/?query=<%= tagsToQuery(tags, antiTags.filter(function (tag) { return tag != antiTags[i]})) %>" class="anti_padtag" title="<%= antiTags[i] %> matches">!#<%= antiTags[i] %></a> + <% } %> + <% } %> </div> </div> - <div style="height: 268px;" id="editorcontainerbox"> - <div id="editorcontainer" style="padding:5pt; height: 600pt;"> - <h1>Current query</h1> - <% if (tags.length == 0 && antiTags.length == 0) { %> - < No current query; please select some tags below to search for pads > - <% } else { %> - <% for (i = 0; i < tags.length; i++) { %> - <a href="/ep/tag/?query=<%= tagsToQuery(tags.filter(function (tag) { return tag != tags[i]}), antiTags) %>" class="tag" title="<%= tags[i] %> matches"><%= tags[i] %></a> - <% } %> - <% for (i = 0; i < antiTags.length; i++) { %> - <a href="/ep/tag/?query=<%= tagsToQuery(tags, antiTags.filter(function (tag) { return tag != antiTags[i]})) %>" class="tag" title="<%= antiTags[i] %> matches">!<%= antiTags[i] %></a> + <div id="editorcontainerbox"> + <div id="editorcontainer"> + <div class="query-refiner"> + <h1>Search for pads that have the tag</h1> + <% for (i = 0; i < newTags.length; i++) { %> + <a href="/ep/tag/?query=<%= tagsToQuery(tags.concat([newTags[i].tagname]),antiTags) %>" class="padtag" title="<%= newTags[i].matches %> matches">#<%= newTags[i].tagname %></a> <% } %> - <% } %> - <h1>Refine your query</h1> - <h2>Search for pads that have a tag</h2> - <% for (i = 0; i < newTags.length; i++) { %> - <a href="/ep/tag/?query=<%= tagsToQuery(tags.concat([newTags[i].tagname]),antiTags) %>" class="tag" title="<%= newTags[i].matches %> matches"><%= newTags[i].tagname %></a> - <% } %> - <h2>Search for pads that <em>doesn't</em> have a tag</h2> - <% for (i = 0; i < newTags.length; i++) { %> - <a href="/ep/tag/?query=<%= tagsToQuery(tags,antiTags.concat([newTags[i].tagname])) %>" class="anti_tag" title="<%= newTags[i].antimatches %> matches"><%= newTags[i].tagname %></a> - <% } %> + <h1>Search for pads that <em>don't</em> have the tag</h1> + <% for (i = 0; i < newTags.length; i++) { %> + <a href="/ep/tag/?query=<%= tagsToQuery(tags,antiTags.concat([newTags[i].tagname])) %>" class="anti_padtag" title="<%= newTags[i].antimatches %> matches">!#<%= newTags[i].tagname %></a> + <% } %> + </div> - <h1>Matching pads</h1> <dl> <% for (i = 0; i < matchingPads.length; i++) { %> <% @@ -125,7 +133,7 @@ limitations under the License. */ %> <dt><a href="/<%= matchingPadUrl %>"><%= matchingPadId %></a><dt> <dd> <% for (j = 0; j < matchingPads[i].TAGS.length; j++) { %> - <a href="/ep/tag/?query=<%= tagsToQuery(tags.filter(function (tag) { return tag != matchingPads[i].TAGS[j]}), antiTags) %>" class="tag" title="<%= matchingPads[i].TAGS[j] %> matches"><%= matchingPads[i].TAGS[j] %></a> + <a href="/ep/tag/?query=<%= tagsToQuery(tags.concat([matchingPads[i].TAGS[j]]), antiTags) %>" class="padtag" title="<%= matchingPads[i].TAGS[j] %> matches">#<%= matchingPads[i].TAGS[j] %></a> <% } %> </dd> <% } %> diff --git a/etherpad/src/plugins/twitterStyleTags/templates/tagRss.ejs b/etherpad/src/plugins/twitterStyleTags/templates/tagRss.ejs new file mode 100644 index 0000000..2d06781 --- /dev/null +++ b/etherpad/src/plugins/twitterStyleTags/templates/tagRss.ejs @@ -0,0 +1,69 @@ +<?xml version="1.0"?> +<% + function inArray(item, arr) { + for (var i = 0; i < arr.length; i++) + if (arr[i] == item) + return true; + return false; + } +%> +<rss version="2.0"> + <channel> + <title> + <% if (tags.length == 0 && antiTags.length == 0) { %> + Latest changed pads + <% } else { %> + <% for (i = 0; i < tags.length; i++) { %> + #<%= tags[i] %> + <% } %> + <% for (i = 0; i < antiTags.length; i++) { %> + !#<%= antiTags[i] %> + <% } %> + <% } %> + </title> + <link>http://liftoff.msfc.nasa.gov/</link> + <description> + Etherpad pads / changes for the query: + <% if (tags.length == 0 && antiTags.length == 0) { %> + Latest changed pads + <% } else { %> + <% for (i = 0; i < tags.length; i++) { %> + #<%= tags[i] %> + <% } %> + <% for (i = 0; i < antiTags.length; i++) { %> + !#<%= antiTags[i] %> + <% } %> + <% } %> + </description> + <language>en-us</language> + <pubDate>Tue, 10 Jun 2003 04:00:00 GMT</pubDate> + <lastBuildDate>Tue, 10 Jun 2003 09:41:01 GMT</lastBuildDate> + <docs>http://blogs.law.harvard.edu/tech/rss</docs> + <generator>Etherpad</generator> + <managingEditor>editor@example.com</managingEditor> + <webMaster>webmaster@example.com</webMaster> + + <% for (i = 0; i < matchingPads.length; i++) { %> + <% + var matchingPadId = matchingPads[i].ID; + var matchingPadUrl = matchingPadId; + if (!inArray('writable', matchingPads[i].TAGS)) { + matchingPadId = padIdToReadonly(matchingPads[i].ID); + matchingPadUrl = 'ep/pad/view/' + matchingPadId + '/latest'; + } + %> + <item> + <title><%= matchingPadId %></title> + <link>http://<%= request.host %>/<%= matchingPadUrl %></link> + <description> + <% for (j = 0; j < matchingPads[i].TAGS.length; j++) { %> + #<%= matchingPads[i].TAGS[j] %> + <% } %> + </description> + <pubDate><%= matchingPads[i].lastWriteTime %></pubDate> + <guid>http://<%= request.host %>/<%= matchingPadUrl %></guid> + </item> + <% } %> + + </channel> +</rss>
\ No newline at end of file diff --git a/etherpad/src/static/css/pad2_ejs.css b/etherpad/src/static/css/pad2_ejs.css index 3b9269e..4b3d7e6 100644 --- a/etherpad/src/static/css/pad2_ejs.css +++ b/etherpad/src/static/css/pad2_ejs.css @@ -245,7 +245,7 @@ a#docbarslider { display: block; height: 0; padding-top: 30px; position: absolut #myswatch { width: 100%; height: 100%; background: transparent;/*...initially*/ } #mycolorpicker { background: url(/static/img/jun09/pad/colorpicker.gif) no-repeat left top; - width: 232px; height: 76px; + width: 232px; height: 140px; position: absolute; left: 13px; top: 13px; z-index: 101; display: none;/*...initially*/ @@ -258,6 +258,34 @@ a#docbarslider { display: block; height: 0; padding-top: 30px; position: absolut #mycolorpicker .n6 { left: 148px; } #mycolorpicker .n7 { left: 175px; } #mycolorpicker .n8 { left: 202px; } + +#mycolorpicker .n9 { left: 13px; top: 34px ! important;} +#mycolorpicker .n10 { left: 40px; top: 34px ! important;} +#mycolorpicker .n11 { left: 67px; top: 34px ! important;} +#mycolorpicker .n12 { left: 94px; top: 34px ! important;} +#mycolorpicker .n13 { left: 121px; top: 34px ! important;} +#mycolorpicker .n14 { left: 148px; top: 34px ! important;} +#mycolorpicker .n15 { left: 175px; top: 34px ! important;} +#mycolorpicker .n16 { left: 202px; top: 34px ! important;} + +#mycolorpicker .n17 { left: 13px; top: 56px ! important;} +#mycolorpicker .n18 { left: 40px; top: 56px ! important;} +#mycolorpicker .n19 { left: 67px; top: 56px ! important;} +#mycolorpicker .n20 { left: 94px; top: 56px ! important;} +#mycolorpicker .n21 { left: 121px; top: 56px ! important;} +#mycolorpicker .n22 { left: 148px; top: 56px ! important;} +#mycolorpicker .n23 { left: 175px; top: 56px ! important;} +#mycolorpicker .n24 { left: 202px; top: 56px ! important;} + +#mycolorpicker .n25 { left: 13px; top: 78px ! important;} +#mycolorpicker .n26 { left: 40px; top: 78px ! important;} +#mycolorpicker .n27 { left: 67px; top: 78px ! important;} +#mycolorpicker .n28 { left: 94px; top: 78px ! important;} +#mycolorpicker .n29 { left: 121px; top: 78px ! important;} +#mycolorpicker .n30 { left: 148px; top: 78px ! important;} +#mycolorpicker .n31 { left: 175px; top: 78px ! important;} +#mycolorpicker .n32 { left: 202px; top: 78px ! important;} + #mycolorpicker .pickerswatchouter { border: 1px solid white; width: 15px; height: 15px; position: absolute; @@ -272,10 +300,10 @@ a#docbarslider { display: block; height: 0; padding-top: 30px; position: absolut } #mycolorpicker .picked { border: 1px solid #666 !important; } #mycolorpicker .picked .pickerswatch { border: 1px solid #666; } -#mycolorpickersave { position: absolute; left: 14px; top: 42px; +#mycolorpickersave { position: absolute; left: 14px; top: 102px; width: 47px; height: 0; padding-top: 20px; overflow: hidden; cursor: pointer; } -#mycolorpickercancel { position: absolute; left: 87px; top: 42px; +#mycolorpickercancel { position: absolute; left: 87px; top: 102px; width: 44px; height: 0; padding-top: 20px; overflow: hidden; cursor: pointer; } #myusernameform { margin-left: 35px; } diff --git a/etherpad/src/static/img/jun09/pad/colorpicker.gif b/etherpad/src/static/img/jun09/pad/colorpicker.gif Binary files differindex 602e7e6..effa3cc 100644 --- a/etherpad/src/static/img/jun09/pad/colorpicker.gif +++ b/etherpad/src/static/img/jun09/pad/colorpicker.gif diff --git a/etherpad/src/templates/admin/pluginmanager.ejs b/etherpad/src/templates/admin/pluginmanager.ejs index 4e08fc9..33b04bf 100644 --- a/etherpad/src/templates/admin/pluginmanager.ejs +++ b/etherpad/src/templates/admin/pluginmanager.ejs @@ -93,18 +93,18 @@ limitations under the License. */ %> <th>Status</th> <th></th> </tr> - <% for (var plugin in pluginModules) { %> + <% for (var plugin in plugins.pluginModules) { %> <tr> - <td><%= pluginModules[plugin].description %></td> + <td><%= plugins.pluginModules[plugin].description %></td> <td> - <% if (plugins[plugin] !== undefined) { %> + <% if (plugins.plugins[plugin] !== undefined) { %> Installed <% } else { %> Not installed <% } %> </td> <td> - <% if (plugins[plugin] !== undefined) { %> + <% if (plugins.plugins[plugin] !== undefined) { %> <a href="/ep/admin/pluginmanager/?plugin=<%= plugin %>&action=uninstall">Uninstall</a> <a href="/ep/admin/pluginmanager/?plugin=<%= plugin %>&action=reinstall">Reinstall</a> <% } else { %> diff --git a/etherpad/src/templates/pad/pad_body2.ejs b/etherpad/src/templates/pad/pad_body2.ejs index a49f453..ca0b3ae 100644 --- a/etherpad/src/templates/pad/pad_body2.ejs +++ b/etherpad/src/templates/pad/pad_body2.ejs @@ -330,15 +330,44 @@ limitations under the License. */ %> <div id="myuser"> <div id="mycolorpicker"> - <div class="pickerswatchouter n1"><div class="pickerswatch"><!-- --></div></div> - <div class="pickerswatchouter n2"><div class="pickerswatch"><!-- --></div></div> - <div class="pickerswatchouter n3"><div class="pickerswatch"><!-- --></div></div> - <div class="pickerswatchouter n4"><div class="pickerswatch"><!-- --></div></div> - <div class="pickerswatchouter n5"><div class="pickerswatch"><!-- --></div></div> - <div class="pickerswatchouter n6"><div class="pickerswatch"><!-- --></div></div> - <div class="pickerswatchouter n7"><div class="pickerswatch"><!-- --></div></div> - <div class="pickerswatchouter n8"><div class="pickerswatch"><!-- --></div></div> - <div id="mycolorpickersave">Save</div> + <div> + <div class="pickerswatchouter n1"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n2"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n3"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n4"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n5"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n6"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n7"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n8"><div class="pickerswatch"><!-- --></div></div> + </div><div> + <div class="pickerswatchouter n9"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n10"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n11"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n12"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n13"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n14"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n15"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n16"><div class="pickerswatch"><!-- --></div></div> + </div><div> + <div class="pickerswatchouter n17"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n18"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n19"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n20"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n21"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n22"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n23"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n24"><div class="pickerswatch"><!-- --></div></div> + </div><div> + <div class="pickerswatchouter n25"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n26"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n27"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n28"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n29"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n30"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n31"><div class="pickerswatch"><!-- --></div></div> + <div class="pickerswatchouter n32"><div class="pickerswatch"><!-- --></div></div> + </div> + <div id="mycolorpickersave">Save</div> <div id="mycolorpickercancel">Cancel</div> </div> <div id="myswatchbox"><div id="myswatch"><!-- --></div></div> diff --git a/infrastructure/ace/www/ace2_outer.js b/infrastructure/ace/www/ace2_outer.js index b0fc20c..e6d430d 100644 --- a/infrastructure/ace/www/ace2_outer.js +++ b/infrastructure/ace/www/ace2_outer.js @@ -14,6 +14,10 @@ * limitations under the License. */ +// requires: top +// requires: plugins +// requires: undefined + Ace2Editor.registry = { nextId: 1 }; @@ -163,6 +167,10 @@ function Ace2Editor() { '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'; var iframeHTML = ["'"+doctype+"<html><head>'"]; + + top.plugins.callHook( + "aceInitInnerdocbodyHead", {iframeHTML:iframeHTML}); + // these lines must conform to a specific format because they are passed by the build script: iframeHTML.push($$INCLUDE_CSS_Q("editor.css syntax.css inner.css")); //iframeHTML.push(INCLUDE_JS_Q_DEV("ace2_common_dev.js")); diff --git a/infrastructure/ace/www/domline.js b/infrastructure/ace/www/domline.js index 38cddf5..90e9943 100644 --- a/infrastructure/ace/www/domline.js +++ b/infrastructure/ace/www/domline.js @@ -101,7 +101,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument) { var extraOpenTags = ""; var extraCloseTags = ""; - ((top == undefined) ? plugins : top.plugins).callHook( + (function () { try { return top.plugins; } catch (e) { return plugins; }; })().callHook( "aceCreateDomLine", {domline:domline, cls:cls} ).map(function (modifier) { cls = modifier.cls; diff --git a/infrastructure/ace/www/linestylefilter.js b/infrastructure/ace/www/linestylefilter.js index d69376a..c163120 100644 --- a/infrastructure/ace/www/linestylefilter.js +++ b/infrastructure/ace/www/linestylefilter.js @@ -238,7 +238,7 @@ linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt) { linestylefilter.getFilterStack = function(lineText, textAndClassFunc, browser) { var func = linestylefilter.getURLFilter(lineText, textAndClassFunc); - var hookFilters = ((top == undefined) ? plugins : top.plugins).callHook( + var hookFilters = (function () { try { return top.plugins; } catch (e) { return plugins; }; })().callHook( "aceGetFilterStack", {linestylefilter:linestylefilter, browser:browser}); hookFilters.map(function (hookFilter) { func = hookFilter(lineText, func); |