mirror of
https://github.com/Alfresco/acs-community-packaging.git
synced 2026-09-16 18:13:21 +00:00
Merged V3.4-TEAM to HEAD
24882: Branch for Team
24883: Version Edition label
24906: Partial implementation of ALF-6566. Replace gears image...
This check-in adds support for the feature as described in JIRA. However we do not yet have
the icon graphics files. I have therefore used some temporary icons in order to flush out
implementation issues and to enable browser-based testing.
A future check-in will add the correct placeholder icons and if they follow the naming
convention, no change in code should be necessary.
Also added and modified some test cases.
24909: ALF-6606: Configurable sorting for Share Document Library. Also change Show/Hide Folder button to icon. (Placeholder icons)
24914: ALF-6564: Initial cut of JMXFormProcessor, will show all attributes of a given MBean and has the ability to persist an attribute value.
24916: Initial Alfresco Team project structure and build targets
24917: First tranche of thumbnail icons for ALF-6566. Replace gears icon.
Have added icons for some basic mime types and removed some temporary icons.
I had to do a clean repo build to flush out the temporary docx and jpeg icons.
24919: svn ignore patterns
24922: Missed files for team build targets
24932: Add a simple AVM to Zip exporter service, initially for use by the site exporter
24935: Start on a java backed webscript to export a site, including all the details (ALF-6567)
24945: Removed two unnecessary TODOs from the RatingService code.
24949: Improved documentation for RatingService webscripts.
Added sample JSON responses for two webscripts.
24956: Implementation of ALF-6792. RatingSchemes should allow self-rating.
Formerly, the cm:creator of a node could never apply a rating to it. An unchecked RatingServiceException would be thrown if they attempted to do so.
With this check-in ratingScheme beans have a new property: selfRatingAllowed. The exception will now only be thrown if a cm:creator attempts to rate their own content in a scheme where this property is false.
The property is true by default and in particular, is true for "likesRatingScheme".
24958: ALF-6599: First pass DND file upload - FireFox4/Chrome support for single/multifile DND upload with basic progress
24961: Added additional data to the response coming from rating.post.
I have added averageRating, ratingsTotal and ratingsCount to that response.
24963: ALF-6625: Balloon Popup Framework. Initial checking. More work maybe required when we start using it, or when designs are complete.
24964: ALF-6598 "Configure Site page refactor"
- page.lib.js - Freemarker lib to sort out used pages and which links and labels to use
- Drag n drop
* now supports horisontal lists
* improved tabfocus and keynavigations
* callbacks can be attached on dnd events: delete-clicks, enter-clicks, element-moved, element-duplicated
- Alfresco.util.isVisible - Checks if the element and all its parents are visible and displayed in the ui.
- Alfresco.util.PopupManager.getUserInput now accepts a "input" parameter that can be set to "text" ("textarea" is default)
- Automatic click listeners can be defined as:
<a href="#onRenameClick" class="${el}" rel="${page.pageId?js_string}">${msg("link.rename")}</a>
which will call:
onRenameClick: function(pageId, anchor) {}
24965: Changing date format of appliedAt JSON property to xmldate.
24971: ALF-6600: Event handling performance improvements for DND file upload
24976: Added team.war to continuous assemble-tomcat
24977: ALF-6600: Initial pass at DND upload highlighting
24979: Add method AuthorityService.getAuthorityNodeRef, and unit tests for it
24980: UI label change for Team install
24981: Set security permission on the new AuthorityService.getAuthorityNodeRef method, in line with the other get methods
24987: ALF-6607 - Likes, favourite and comment actions. Also DocLib panel redesign. Updates to Rating Service to better match Team use cases.
24989: ALF-6601: Added JavaScript multipart data constructor for FireFox 3.6 support
24990: Fix "Access Denied" error when navigating into a "Liked" folder.
25000: Merged V3.4 to V3.4-TEAM
24999: ALF-6764 - Updated copyright year to 2011
25004: ALF-6601: Set file size limit, HTTP status code error handling
25007: Add user, group and person ACP exports to the Site Export webscript.
(The user export is provisional, pending a service level way to access the user NodeRef)
25008: ALF-6788: Update dashboard template to provide full width component and presets updates to reflect new default layouts.
25017: Initial check-in for ALF-6809. A service to managed deleted items.
This check in adds a basic REST API for GETting and DELETEing deleted items from the archive store.
JUnit tests of the REST API are included but are not yet complete.
25018: Trivial fix for failing test case related to ALF-6809
25019: A previous check-in (25017) accidentally included an extra Java file that wasn't ready.
File is related to ALF-6809 and will be implemented today.
This check-in removes the internals of the class to allow it to compile.
The class is not injected into the spring application context and is essentially dead code pending its implementation later.
25027: Adding nodeType to the archivednodes.get webscript response.
Requested by UI as part of ALF-6809.
25035: ALF-6789: Personal dashboard welcome (with wireframe styling)
25036: ALF-6782 - Undelete administration console page (WIP)
ALF-6784, ALF-6786, ALF-6787
25037: ALF-6564: Added operations to default form, all parameter-less operations are displayed as a button on the form. Clicking a button executes the operation after saving all attribute values.
25038: Added a node filter to the archivednodes.get webscript. Currently excluding cm:thumbnails.
A new bean on the script's controller class that allows injection of nodetypes to be excluded.
Should be trivial to exclude other node types later and easy to exclude based on other criteria.
25039: Part of ALF-6809. Deleted items were returned from archivednodes.get in the wrong order.
They are now sorted by archive datetime most recent first. (Was previously sorted with most recent last.)
Also switched the test case, which was backwards too!
25040: Changing some copyright headers from 2010 to 2011.
25041: ALF-6564: JMX forms can now be configured with selective attributes and the set of operations. Also includes an example form configuration for the outbound email almost matching Linton's wireframes.
25042: ALF-6788: Fix rendering of old (V3.4) user dashboards stored in AVM with new Team layout
25044: Part of ALF-6809. Added displayPath value to archivednodes.get.
25047: Part of ALF-6809. Reconfiguration of cm:thumbnail archive behaviour.
Formerly, we were archiving cm:thumbnails on deletion and filtering them from the archivednodes.get webscript which was not ideal as they remained in the archive.
This check in removes the filter on the GET webscript and prevents cm:thumbnails from being archived in the first place.
25049: ALF-6782
- added Trashcan to admin tools menu
- cleaned up list, show display path
25050: ALF-6782 - css tweaks
25052: Added check for multiple calls to onHistoryManagerReady() as workaround for issue with multiple History Manager objects when using Alfresco.util.DataTable.
25053: Test case refactoring as part of ALF-6809
25055: ALF-6803: First drop of aggregate file upload progress information.
25056: Part of ALF-6809. A preliminary PUT webscript that is used to restore nodes from the archive to their original loaction.
Currently only works on a single node per call (which is what the JIRA requires).
Test code currently incomplete. I'm checking in now to give UI something to work with.
25057: Fix for failing test case, which was part of ALF-6566.
25058: ALF-6567 - AVM importer, which can load a zip file's contents into a specified AVM filesystem. Includes a bootstrap wrapper around the main importer.
25068: Part ALF-6893: RTEAM 03: Expose restrictions using RepoAdminService
- Subtask of ALF-6832: AT17: License restriction reporting
- Added RepoAdminService.getRestrictions in Java and Webscripts APIs
- Currently nulls returned indication 'no restrictions'
- Cleaned up unused AdminService
25069: ALF-6625 - adds a switch to control what calendar views are enabled and switches off Day, Week and Month views in Team.
25073: Test case overhaul and minor tidying of code. Part of ALF-6809.
25074: ALF-6803: Style updates to upload progress info
25075: ALF-6601: Updated in-memory file upload check so that failure is based on total (not individual) file size.
25081: Merged V3.4 to V3.4-TEAM
25051: Build Fix: ALF-6865 CopyServiceImplTest.testCopyToNewNodeWithPermissions failing on permission copying
25082: Part ALF-6893: RTEAM 03: Expose restrictions using RepoAdminService
- Subtask of ALF-6832: AT17: License restriction reporting
- Added RepoAdminService.getUsage in Java and Webscripts APIs
25084: Improve how the Site Exporter gets at the users for a site, and have the user authentication details export skipped if a non-repository based authenticator is enabled
25085: Final part of ALF-6809. Support for paging the results from archivednodes.get.
Follows the standard maxItems, skipCount convention and enables paging in the trashcan view automatically thanks to Kev's use of the convention.
25088: Final, final part of ALF-6809. Throwing 4xx, 5xx exceptions for nodeArchiveService-level failures to restore nodes
25090: ALF-6601: Updated in-memory upload limit to be configurable
25096: ALF-6601: Updates to DND highlighting and behaviour, set correct upload limit in bytes, NLS updates
25101: Fixing failing test cases. Fallout from recent changes to the JSON response formats in these webscripts.
25103: ALF-6613 - SpringSurf improvements to allow easier refactoring of Document Details page
- latest SpringSurf libs with RequestCachingConnector improvements
- removed manual request level caching of remote calls responses in web-tier components - now completely automatic
25104: ALF-6803: DND upload dialog styling
25106: ALF-6802: Added feature detection to disable drag'n'drop events (disables for IE6, IE7 & IE8)
25108: ALF-6564: Added a check to the JMXFormProcessor to ensure the current user is an administrator. Also relaxed the rules in the checkbox control so it can be used for string values not just boolean values.
25113: ALF-6789: Updated CSS to support IE6/IE7
25116: Prevent server-side exception when navigating trashcan; related to paging. (ALF-6809)
25117: ALF-6824 - Only show "Like" and "Comment" actions if a user has the correct permissions. Additional fixes for IE7.
25118: Fix incorrect category aspect name. Missing file from r25117
25119: ALF-6645 - Share and Team branding updates
25121: Removed erroneous comment block
25123: Merged HEAD to BRANCHES/V3.4-TEAM:
25115: Fixes: ALF-6336 - resolved incorrectly translated date formatting strings.
25124: Add a new bootstrap component for bootstrapping Sites. Handles the contents, AVM and authentication, people and their group membership to follow.
(Uses singleton spring beans in line with the patch service's use, to ensure that when loaded from a bootstrap extension things still occur in the correct order)
25128: Merged V3.4 to V3.4-TEAM
25127: Merged V3.3 to V3.4
25126: ALF-6903 - Share theme feature does not work. Also fixes issue with MultiThreadedHttpConnectionManager in SpringSurf.
25130: Continue with the site bootstrapper - finish supporting the loading of the site contents ACP
25132: Work on ALF-6832:TR25: License restriction reporting
- ALF-6893: RTEAM 03: Expose restrictions using RepoAdminService
- ALF-6911: RTEAM 02: Record and expose system attributes
- Added RepoUsageComponent
- Unit test incl. testLicenseUse
- Persists and retrieves usage data using AttributeService
25133: ALF-6789: Added "Close" link to dynamic-welcome dashlet and associated webscript
25135: ALF-6789: Add missing localization
25136: ALF-6601: Defensively code against missing config
25137: Fix up of transfer test.
25138: Flattening of user preferences remote calls - ensures /preferences hits the RequestCachingConnector - reduces no. of remote calls by 3 for the doclib and by 4 for a site dashboard.
25139: ALF-6804: Disable drop outside of document list
25140: ALF-6887 - for sending HTML emails
- prelim support - either text explicitly starts with "<html" and/or is passed via new HTML param
25141: Updated version to 3.5.0 for Team
25142: ALF-6834 - activities feed email notification (1st cut)
- for sprint 1 demo (ALF-6928, ALF-6929, ALF-6931, ALF-6932)
- note: to demo ... manually copy "activities-email.ftl" into repo (/Company Home/Data Dictionary/Email Templates/activities) and configure your own email address (for one or more users)
25145: ALF-6602: Added first time instructions for DND upload
25147: Merged HEAD to BRANCHES/V3.4-TEAM:
25100: Fix for build issue Steve was encountering on new build boxes using Ant 1.8.x
25151: ALF-6790: Updated CSS and images to match latest mockups
25161: Basic support for canned queries
- ALF-6910: RTEAM 01: Query support for system-wide attributes (ALF-6832)
- At this stage it only has support for count-style queries
- General-purpose change that will be needed for main Enterprise branches
25162: Temporarily disables the balloon framework while I fix a bug in it.
25163: Basic support for canned queries: extended tests
- ALF-6910: RTEAM 01: Query support for system-wide attributes (ALF-6832)
- General-purpose change that will be needed for main Enterprise branches
25164: Further Site Export/Bootstrap work - support importing People (profiles for users), and placing them into the correct groups
25165: ALF-6905 - RTEAM 04: Add restrictions to trial license
25166: ALF-6644 - Theme per site.
- Theme selection for a site and its child pages can be made in the Customise Site page
- Framework now allows theme per application, site or page.
25167: ALF-6790: First pass at new site dashboards welcome dashlets
25168: ALF-6832 - RTEAM 19: Update DescriptorService
25169: ALF-6906 - RTEAM 18: Report Team or Enterprise in startup log
25171: ALF-6998 - activities feed email - reuse Share messages (including L10N)
25172: ALF-6910: RTEAM 01: Query support for system-wide attributes
- Added and call canned queries for users and documents
- ALF-6832 TR25: License restriction reporting
25175: ALF-6998 - activities feed email - fix build copy of activity-list*.properties
25176: ALF-6962 - activities feed email - use configured share url (from sysAdminParams)
=> share.protocol, share.host, share.port, share.context (note: you may need to override for dev/demo env)
25178: ALF-6564: TR12: Implement JMX Form Processor. Added tests, fixed a couple of bugs in form processor and added all Mike's form config for MBeans we're provisionally exposing.
25187: ALF-6998 - activities feed email
- quick fix if running within repo-only context (eg. via Eclipse)
25188: Prevented NPE with Enterprise edition built as community.
25189: Expose getAllowWrite on the TransactionService API
- This is a user-independent flag as opposed to isReadOnly, which makes allowance for the 'System' user
25190: Work on ALF-6832:TR25: License restriction reporting
- ALF-6893: RTEAM 03: Expose restrictions using RepoAdminService
- Use TransactionService as the source of 'isReadOnly'
25191: Fix to issue where null could be passed as URI Tokens
- fixes issue where pages failed to render on first display since rev 25166
25192: CSS tweak
25194: I18N'd system startup message
25195: Restrictions now sets current time and readOnly property.
25196: ALF-6790: Added user prefs to enable site welcome dashlet visibility
25198: ALF-6790: Fix user close welcome dashlet persistence. Added site welcome dashlet close reload.
25200: ALF-6803: Update upload dialog title to display (encoded) folder name (not entire path)
25203: ALF-6834 - TR15: Activities feed email notifications
- ALF-6931 - RTEAM 23: update activity feed DAO to filter by min id and/or max items
- ALF-6929 - RTEAM 21: now uses last feed id for each user
- minor cleanup (eg. tweak template to deal with null message)
25204: ALF-6790: Fixed broken site preference logic
25206: Checkpoint ALF-6608 - Inline property editing - name field. Also paves the way for ALF-6611 - Inline property editing - any meta field. Currently does not constrain input values, nor handle repository errors (e.g. duplicate name).
25212: ALF-6602: Updates to reflect latest designs
25213: ALF-6564: More MBean form config
25248: A new schema version range for 3.5
25249: ALF-7049 - RTEAM 12: Disable Alfresco Explorer
25252: ALF-7050 - RTEAM 09: Disable MT
25263: Fix trailing comma for IE browsers
25268: Implementation of ALF-6829 Popularity of a node (RatingService).
This check-in is actually a fairly generic support for rolled up property values within rating schemes.
Popularity is currently the only concrete rollup in the system, but it should be possible to add more without too
much difficulty.
Given the published API for the rating service, we have added rollups for "ratingCount" and "ratingTotal" for the built-in rating schemes (likes). Therefore searching/sorting on either cm:likesRatingSchemeCount or cm:likesRatingSchemeTotal, both of which are defined in an aspect cm:likesRatingSchemeRollups should give popularity for the likes rating scheme.
Additions to the content model.
I have added aspects, properties for the built-in rollups, namely count and total.
Spring changes
The rating scheme(s) now have rollups injected into them. These rollups are algorithm classes that know how to calculate the rolled up props.
Naming conventions are used to determine the output property and are captured in RatingRollupNamingConventionsUtil.java.
API changes
New methods: RatingService.getRatingRollup(NodeRef, String, String)
& RatingScheme.getPropertyRollups()
Changes to the RatingService implementation and JUnit test code.
To roll your own rating rollups:
To add your own rating rollup, you need to reuse one of the existing AbstractRatingRollupAlgorithm subclasses or create a new one.
That class will produce the value of the rolled up property by iterating the ratings in the given rating scheme for a given node.
You need to inject your rollup algorithm into the rating scheme bean in rating-services-context.xml
On applyRating() and removeRating() the RatingService will check the rating scheme for any registered rollup algorithms and will have them recalculated.
It will then use the naming conventions described in the JIRA and in RatingRollupNamingConventionsUtil to get aspect/property names for each of the rollups.
It will then add the property value in the normal way.
Therefore, you need to extend the content model to include the expected aspect and property values. Follow likesRatingScheme for a sample.
25273: Fix failing unit test.
25274: DocLib sorting support for "popularity" (Likes rating scheme)
25277: ALF-6602: Updated instructions to reflect new design. Info shown now dynamically based on site ownership/access rights/browser feature support
25278: Merged BRANCHES/V3.4 to BRANCHES/V3.4-TEAM:
25267: ALF-1070 - if site/user is deleted then immediately clean associated site/user feed
25279: ALF-6601: Updated to handle 0 byte dropped files (or folders)
25280: ALF-7009 WIP checkpoint
- Also removed some code that is obsolete since ConsoleTool class extends Alfresco.component.Base
25286: ALF-6599: Changed folder DND target back to image (not row)
25298: ALF-7009 - Upload and replace Share logo
25311: ALF-7080 / ALF-7002 - ActivitiesFeed subsystem (+ option to enable/disable job triggers)
- moved ActivitiesFeed into subsystem for dynamic mgmt via JMX
- FeedNotifier repeat interval can be dynamically changed
- also added "enabled" property to AbstractTriggerBean => FeedNotifier job can be disabled / re-enabled
25312: ROLLBACK (Partial) 25249 ALF-7049 Disable Alfresco Explorer.
25313: ROLLBACK 25252 : ALF-7050 - RTEAM 09: Disable MT
25317: ALF-6930 - bootstrap / patch activities email template
25331: ALF-6890 - RTEAM 16: License-based restrictions: Number of users
25333: Merged BRANCHES/V3.4 to BRANCHES/V3.4-TEAM:
25319: Build/test fix (fallout from ALF-1070)
25322: Build/test fix (fallout from ALF-1070)
25356: ALF-6930 - bootstrap / patch activities email template
- missed file, sorry !
25358: ALF-6834 - Activities email: tweaks
- pass through repeatInterval (to template model)
- add exclude email list (eg. for default admin)
25360: RTEAM 28: License restriction reporting: Force refresh
- Added API for selective updates of usage data based on an enumeration: USAGE_USERS, USAGE_DOCUMENTS or USAGE_ALL
- When people are added, for instance, usage will be updated and then retrieved for checking.
25363: ALF-6639 - Default collaboration dashboard
- NOTE: may need Team overlay version on merge if this change is *not* the default for Swift
25364: Modified usage/restriction admin webscripts to use a common FTL lib for the json output and added some missing quotes around the license mode value.
25365: ALF-6597: Added DashletTitleBarActions widget and applied to WebView dashlet
25367: ALF-7082 - Remove Network Dashlet
- Removed network dashlet from codeline
- Support in WebScripts to allow hook for override of exception handling from webscripts for specific use cases
- Surf LocalWebScriptRuntime overrides error handling looking for specific case of SC_NOT_FOUND - and silent ignores missing webscript components
- Improved Share handling of missing webscript components that have already been bound into a dashboard (i.e. not a missing "slot" but an existing component binding that points to a missing webscript URL) - this will also allow for easier removal of other existing dashlets in the future without requiring repo-side patches or similar.
25369: ALF-7042 (ALF-6832) RTEAM 28: License restriction reporting: Force refresh
- Added unit test for update WebScript
25375: Implementation of ALF-7024. Document versions service/webscript needs to return avatar url.
The avatar url has been added to the JSON response as requested.
If there is no avatar, a JSON null is returned as requested.
25377: Add maxDocs, maxUsers and license mode to License JMX bean
25378: Adding additional property to version.get webscript: a correctly-formatted ISO8601 date.
This has been added as requested in the comments of ALF-7024.
25381: Refactor of LicenseComponent and related to produce LicenseMode in descriptor (ALF-6907 RTEAM 19)
- Need actual enum to do later usage updates according to mode
25382: ALF-7053 - RTEAM 07: Disable Transfer
25387: ALF-6564: Finished JMXFormProcessor (again). There is now a configurable list of operations to ignore, revert is ignored by default. The labels for the buttons are also localisable now.
25390: Fixed up License MBean after changing the descriptor API
25391: ALF-6911: RTEAM 02: Record and expose system attributes
- Added job locking around individual usage queries
- It is possible to concurrently update user and document counts
- Exposed true/false return value on updates and added this to usages webscripts
25392: Switched version edition back to Community
- If we distribute Team using a community build, then we should know about it.
- Team functionality is triggered by an Enterprise build or TEAM license.
25393: Undid rev 25392
25394: Work on ALF-6832:TR25: License restriction reporting
- ALF-6893: RTEAM 03: Expose restrictions using RepoAdminService
- ALF-6911: RTEAM 02: Record and expose system attributes
- Added RepoUsageMonitor
- Self-starting schedule
- Only checks for restrictions that are in place
- Issues warnings and errors; puts system into read-only mode on violation
25403: ALF-6890 - Switch over of user query to database backed query.
25408: WIP checkpoint for Agenda view refactor:
- Adds Alfresco.util.friendlyDate to supply "Yesterday/Today/Tomorrow" style date
- refactors getEvents into a common function in calendar-view.js (calendar-view-month not touched because it gets elements from the DOM rather than API)
- Uses DataTables to display agenda events (currently unformatted)
25410: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/V3.4-TEAM:
25409: Merged BRANCHES/V3.4 to BRANCHES/DEV/V3.4-BUG-FIX:
25407: Merged BRANCHES/V3.3 to BRANCHES/V3.4:
25401: Allow continuous.xml database drop/create on postgresql and mysql to support the database being on a different machine
25406: We no longer need a 2nd _test database for the unit tests, so remove the code that created/removed them during the continuous build
25411: Fix to allow application logo to be uploaded with same filename as a previous logo.
25416: Implementation of ALF-7100. Comments webscript doesn't return dates in iso8601.
I added iso8601-formatted date fields jsut as for ALF-7024.
25418: Implementation of ALF-7173. Remove the RatingService restriction whereby a single user can only rate a single node with one RatingScheme.
Change to the RatingService javadoc so that it doesn't mention the restriction.
Additional method in RatingService: getRatingsByCurrentUser - to return multiple ratings.
Reimpl's testOneUserRatesInTwoSchemes test case from a -ve to a +ve test case.
Rewrote the REST test cases slightly to cover the case of a single user multiply rating a node.
Various changes through the apply() case to support this.
25419: Change the Site Loading for ALF-6567 from a bootstrap to a patch. This means that if a site is loaded then deleted, it won't be re-loaded again.
25420: Fixed unit test for ALF-6911: RTEAM 02: Record and expose system attributes
- Forgot to prompt user usage changes to check numbers against
25422: Addition of selfRatingAllowed field to ratingdefinitions.get webscript.
As this is now a configurable property on a scheme, it should be reflected in the REST API.
25423: Node rows that transition to the deleted state (not archive) are given type sys:deleted
25425: Add an example extension context file to patch-load an exported Site, and allow the import path to use defaults to reduce the number of settings required
25426: ALF-6597: Added temporary tooltip code for DashletToolbarActions (and updated to WebView dashlet to use it)
25427: ALF-6789: Removed dynamic welcome dashlet from add dashlets menu
25428: ALF-6599: Removed encoding of spaces in displayed location name on DND upload to folder
25430: ALF-6890 - tweaks to query and person service for user limit stuff.
25432: ALF-6597: Updated DashletToolBarActions to ensure fade in on first mouseover
25433: Implemented ALF-6613, ALF-6614, ALF-6615, ALF-6616, ALF-6617, ALF-6618, ALF-6619, ALF-6620, ALF-6621, ALF-6622 - PART #1
- ALF-6613 TR22: Document Details page improvements
- ALF-6614 Page redesign and refactor
* Components are atomic and doesn't need global events to work.
- ALF-6615 Document Actions panel
- ALF-6616 Tags panel - NEW, replaces the old "info (tags+permissions)" component
- ALF-6617 Share links panel
- ALF-6618 Properties panel
- ALF-6619 Permissions panel - NEW, replaces the old "info (tags+permissions)" component
- ALF-6620 Workflows panel
- ALF-6621 Version History panel
- ALF-6622 Comment component redesign and refactor
- alfresco-macros.lib.ftl
* <#function uriTemplate id>
Helper for getting a uriTemplate in freemarker
* <#function userProfileLink>
Helper fopr rendering a userProfile link in freemarker
- alfresco-util.js - Rhino Javascript-helpers
* function error(code, message, redirect)
Helper for redriting and throwing a webscript error
* function param(name, defaultValue)
Helper for placing a webscript "param" in the model, lloks for param in the following order args, page.templateArgs, properties, defaultValue.
If no value is found and no default value was given an error is thrown.
Useful to avoid webscripts "crashing" when accessed from /service/ rather than from /page/ path, i.e. when refreshed/reloaded using ajax.
* function getRepositoryUrl()
* function getRootNode()
* function getDocumentDetails(nodeRef, site)
- alfresco.js
* New in Alfresco.util.DataTable
c.dataSource.doBeforeParseData - to modify response before rendering, i.e. if an array is the respons rather than an object
c.dataTable.config.className - if another css class than alfresco-datatable shall be used
c.paginator.history - set to false to avoid browser history management to kick in
reloadDataTable() - to reload
getData(record) - to get data related to a row in the table
* sanitizeMarkup() - moved out code from request(), strips out <script> tags from html
* New in Alfresco.base.Component
- createYUIButtons()
- attachLinkClickListeners()
- refresh(url) - gets new markup from server and replaces the old and unregisteres the js component instance
- base.css
* .alfresco-twister-actions - use this class to place actions in the twisters that are visible when twister is opened
* .document-version - common css class for version label
* .alfresco-datatable - Common styling for datatables created from Alfresco.util.DataTable,
gives list like appearence and removes headers and bprders.
- NOTE! Tested in FF3.5 & SF4, PART #2 will contain:
x-browser testing, tidy up comments form, social gadgets in header, activities after new version upload
25437: ALF-6789: Added confirmation dialog for welcome dashlet close
25439: More WIP for Team's Agenda view. General clean up, code commenting and start of styling.
25443: ALF-6597: Added actions to remaining dashlets
25451: Site label suffix removed from title bar
25452: ALF-7053 - Disable Replication Service
25453: ALF-6599: Disabled DocLib DND upload when viewing non path filters (and fixed filter view bug that was previously introduced)
25454: Stub out the user upload via CSV webscripts
25455: Implemented ALF-6613, ALF-6614, ALF-6615, ALF-6616, ALF-6617, ALF-6618, ALF-6619, ALF-6620, ALF-6621, ALF-6622 - PART #2
- components doesn't break when accessing a working copy OR a repository document (non site)
- remove som unecessary code that slipped in with comments-list.js
- "Add comments" now clears the editor before the next add
- Comment paginator is only visible when necessary (happens to all paginators by default,force show with c.paginator.hide=false)
- removed the document-details.ftl instantion of the javascript class
- version panel isn't rendered on doc details page for working copies
- versions panel had white background under text "No previous verisions exist"
- code commenting sweep
25457: ALF-6599: DND event listener fix
25460: CSS tweak to document path
25461: ALF-6790: Updated links for invite and upload for managers/contributors
25462: ALF-6811: Added upload users CSV button to existing user admin console page. Stubbed code for invoking WebScript
25470: Some build fixes
- in general running without an authenticated user
- getPerson -> getRestrictions without any security context
25473: Added csv, xsl, xslx formats/mimetypes to default list for webscripts.
25475: ALF-6608: Inline property editing - name field
ALF-6625: TR04: Balloon popup (tooltip) component
Also Document Library restyling: rollover style, text removed from most buttons, new icons.
25476: Repository Browser brought up-to-speed with latest Site DocLib changes.
25477: TEAM build fixes
- fix unprotected service not to use public services - allows repoAdminService to be wired up to personService
- There may be collateral damage to test using the messageService
25482: Add the Apache Commons CSV library, and also fix the classpath breakage caused by the postgresql jdbc jar switch
25483: Implementation of ALF-7005. TR24: Remove inappropriate rule script actions.
Both sets of script actions (email templates and scripts) are built up using FolderContentsParameterConstraint objects.
Using this class a location in the repo is specified and all cm:content children under that location (recursive) are included.
I have added a new, optional property to that class which allows the specification of a list of file extensions, which is used as an inclusion filter for the content nodes.
I decided against using a MIMEtype-based filter as there are situations where users add e.g. .js files as text/plain.
Then I inject "js" and "ftl" as inclusion filters in the relevant action-constraint beans in the action service.
We can easily add further file extensions should it be necessary.
25484: ALF-6597: Fixed IE6 selector issue
25486: ALF-6597: CSS correction to r25484
25488: Small adjustments to descriptor logging during startup.
25489: Team Eclipse project
25491: ALF-6789: CSS tweaks to welcome dashlet columns
25492: Get the basics in place for the user CSV upload - provides a sample csv file, loads it, process the contents and reports a JSON response, but doesn't yet create the users
25495: ALF-6642: TR08: Site only view - remove Repository view.
Copy and Move to dialogs only display Sites destination in this mode.
Note: Page mapping not removed until it's clear how this will integrate with the installer; hence manually browsing to the Repository Browser is not pretty right now.
25496: Minor follow-up fix for Repository Browser.
25497: Support for ALF-6642 on details pages.
25499: Document Library sort improvements: individual sort parameters can now be given a default sort order (like the Share search results page). Currently configured as name: ascending, popularity: descending.
Also added support for "#upload" in URL to show the upload dialog.
25500: ALF-7120: TR03: Test and integrate sample site into bootstrap process
NOTE: This will install the Work In Progress sample site to your repository next time you start the repo. 2 new users will be added and will count towards your allocated users, you can safely delete the site and the users, they will not get re-loaded.
25501: When generating the example file for the user CSV upload, have the webscript generate .xls and .xlsx versions, as well as the previous .csv one.
25502: ALF-6790: Update upload link to #upload to get upload dialog
25503: Team build fix: Fix message service tests after changing the beans wired up
25505: New requirements for ALF-6617 "Share links panel", now only displaying link to current page
25507: ALF-6640 - WIP. Initial styling pass, event actions, etc.
25511: ALF-6789/ALF-6790: Removed old welcome dashlets
25512: Resolve ALF-7099: Duplicate view:reference entries in an ACP export created using multiple noderefs
25514: General cleanup of implementation and use runAs to query Admin-only service
25516: More ALF-6893: RTEAM 03: Expose restrictions using RepoAdminService
- Added 'licenseValidUntil' to web script returns (may be null)
25518: Harden MessageServiceImplTest against leaked transactions
25519: Refactor the common code for dealing with tenant usernames + tenant domain checking, during person creation, out to the person service
25521: ALF-7099 export follow up: emit associations after all objects
25523: Add support to the User CSV Upload webscript to actually create the people and users, using the new common service methods in common with share
25524: Implementation of ALF-7093. Transfer/replication actions must not be displayed when the transfer service is disabled.
Note: It is the ReplicationService which is enabled/disabled as opposed to the TransferService.
A new webscript has been added (available at GET /api/replication-service-status) which returns
{"data": {"enabled": true}}
Also a new REST test case.
25525: ALF-6911: RTEAM 02: Record and expose system attributes
- made getRestrictions() accessible to 'guest'
25526: Update the user csv upload webscript with some debug log entries, and excel support
25528: ALF-6602: Updated to new (temporary) images, updates to CSS
25535: Removed deep svn:mergeinfo. Please merge from base of code lines and remove spurious svn:mergeinfo
25536: Merged V3.4 to V3.4-Team
25399: Fix for ALF-6991: "Connection pool causes poor performance in some test suites"
- applied constructor fix recommended by https://issues.apache.org/jira/browse/DBCP-330
25400: Fix for ALF-6991: "Connection pool causes poor performance in some test suites"
- commit missed file
25474: Eclipse classpath tweaks to prevent element-based entry for Commons DBCP
25537: ALF-7094: First cut of TR24: JSF-based login screens should warn unsupported when in Team mode. The wording needs reviewing and changing as does the position and styling of the text.
25542: Implementation of ALF-7182. TR20: When a user 'likes' a document it appears in the activities feed.
MikeH gave me the JavaScript changes for this in Share tier. Thanks Mike.
I added some ftl and properties.
25546: ALF-6602: Further image and CSS tweaks to doc lib assistance
25548: Enhancements to user limit error reporting (ALF-6890: RTEAM 16: License-based restrictions: Number of users)
- Report the usernames being added that generate the limit violation
25549: ALF-6789: CSS updates
25551: Fixed bug in Alfresco.util.DataTable when setting default css class name (appearing i.e. on trash can admin ui)
25552: Minor cleanup in createPerson code.
25554: ALF-6635 "TR12: Browser based administation - JMX admin console pages"
25557: Updated version of sample site for Team, the full page width welcome dashlet is now present for both users.
25559: First phase of ALF-6835:
- Share now retrieves repository license/restrictions via REST API on first user login
- Dynamically applies override config onto Alfresco config based on license info - allows Enterprise/Team specific tweaks to UI etc.
- also constructs an object representing the license/restrictions that can be read by Surf components
- Share Footer component now dynamically switches Community/Enterprise/Team logos and text based on config
- Removed team project from source tree - NOTE: remove it from your local Eclipse projects
- Removed team build targets - NOTE: devenv team targets will no longer work
- Removed enterprise overlay for footer and share enterprise logo (no longer required due to dynamic footer configuration)
25562: ALF-6835 - About Share dialog now displays appropriate edition logo and background based on license details
25566: Allow users of the Mail action to pass in extra model options for their templates to use.
25568: When processing user CSV uploads, skip cleanly over blank lines
25570: ALF-6811: Updated users admin console page and associated scripts to process WebScript feedback
25572: ALF-6884 - TR25: Reload license file on live server via JMX operation on LicenseDescriptor mbean.
25575: Agenda View WIP. Added add/edit/show more events functionality, bug fixes and styling. Updated Calendar API to include event description!
25578: Bring user limit warnings in line with PersonService (create time) warnings
25579: Repo usage monitoring done every 12 hours
25580: ALF-6599: Update folder target highlighting & update temporary images
25583: Fixes bug in Calendar Agenda view - number of days shown by default (was: from now - end of current month, is: from now until now + 30)
25584: ALF-6602: Fix broken links on assistance panel
25585: Branding and CSS tweaks from Linton
25587: Wrap the User CSV upload result json in a data block, to better fit the current pattern
25591: In the User CSV upload webscript, correct line numbers in error messages for excel uploads
25593: Dashlet title rollover behaviour changes. Insitu edit balloon now removed when textbox loses focus.
25596: Impl of ALF-7175 Comment order ... changed.
This check-in adds a repo-side webscript parameter to reverse the order of comments
25599: ALF-7233 remove doc for changing server.transaction.allow-writes
25601: ALF-6811: Update to users.js to handle modified JSON response from WebScript
25602: Agenda View, Bug fixes and CSS tweaks.
25605: The empty 'Operations' set no longer appears in view mode and made the mail.password field behave like a password field
25606: Tweak the JSON to better fit the current layout standards
25607: Add a few more fields to the User CSV upload, based on the fields in Share
25609: ALF-6645 - Branding tweaks
25613: Help URLs moved to new edition based config - removed enterprise overlay.
- NOTE: final 3.5 URLs still to be decided!
25624: ALF-6789/ALF-6790: Updates to CSS/DOM to achieve completely fluid vertical and horizontal layout
25626: ALF-6789: Updated profile to provide #edit hash and welcome daslet to make use of it
25628: ALF-7207 - activities feed email / mail action executor
- mail action executor should not get (+ auto-create) person when running as System
- prepare / send email for each person as a separate txn
- also: add actual / max feed item counts to template model (as per ALF-6834)
25631: Share Admin Console tool groupings
- Implemented basic groups of tools in the admin console
- First attempt at grouping tools - needs review by Linton/MikeF
25644: Disable repository searching for team license configuration.
25646: ALF-6835 - License details shown on License Descriptor admin page
- Fixed up out-of-date JMX form bean names (changed on repo side since original JMX form config)
25647: Team Agenda View - no events text, and other minor fixes
25648: ALF-6811: Updates CSV WebScript response, added HTML format handling, added results panel to user console.
25650: File missed from check in 25647
25652: Start to convert the User CSV uploader to using localised error messages and error responses rather than non-localise exceptions
25653: Added MikeF's url templates for ALF-6628 TR23: Preview support for Flash Video and HTML5 video.
25654: ALF-6835 - Edition Interceptor improvements
25655: Update how the User CSV Upload webscript returns messages and errors. Makes use of a property loaded via a resource bundle, and a new extension to WebScriptExtension which is driven by a supplied ResourceBundle, rather than the system-wide ones (which don't hold webscript specific messages)
25656: ALF-6789/ALF-6790: Updated text, CSS/DOM tweaks & update to site-members to provide all members hash for welcome dashlet
25658: ALF-6811: Updates to HTML format response for CSV request to support HTML uploader
25659: Partial implementation of ALF-7230.
This check-in changes the bootstrap data within the acp such that the sample JavaScript files in Data Dictionary/scripts are now bootstrapped as *.js.sample. Their content has not been changed.
Note that this applies to backup.js, example test script.js, backup and log.js, append copyright.js, alfresco docs.js and test return value.js.
A separate solution will be provided for the command-*.js scripts.
25660: Better reporting of the script causing stream errors
25661: ALF-7231: RTEAM 32: FileFolderService method to get localised file
- Locate the base translation using the well-known QName path (selectNodes) - this is the current way.
- Call this additional method to locate any localized siblings
25662: ALF-7263 - Track multiple reasons why we are read only otherwise we can't go back to read/write.
ALF-7220 - Repo Usage Component Unlock
25663: ALF-7256 - Ensure license reload does not damage server after upgrades
25666: ALF-6811: Fix success message for all users uploaded
25668: Increased user limit to 10 users for trial license
25672: Some formatting
25673: Minor comments format from Javadoc to inline
25674: User count reporting: Keep track of disabled users on person
- Disabling a user adds an aspect to the related person object
- Should be able to export after disabling user
- Don't count disabled persons
- User count is reduced by 1 to cater for 'guest'
- RTEAM 16: License-based restrictions: Number of users
25679: A little more information is now returned if an error occurs whilst persisting MBean attributes or invoking an MBean operation.
The sample site root node is prevented from being archived when it's deleted during the sample site bootstrap process.
25681: ALF-6789: Change "Close" to "Remove"
25685: Agenda View: Fixes Tagging.
25686: IE fixes and slight change to the "automatic" binding from button/links against a component (value/rel attribute is now treated as a simple string instead of as an object)
25688: Agenda view - new sketch logo from Linton for when there are no events
25689: Feed edit icon css class
25690: Invite test uses disabled users
25691: ALF-7229 - partial (for Activities Feed Notifier)
- also cleanup IoC deps
25693: Work in progress ALF-6593: TR04: Update dashlets to provide consistent look & feel, include thumbnails, help text, action links where applicable
25694: MERGED V3.4-BUGFIX to V3.4-TEAM
24898 : Fix to FixUserQNamesPatch
25695: ALF-6789/ALF-6790: Added new icons, removed old ones
25697: ALF-7231: RTEAM 32: FileFolderService method to get localised file
- Fixed extraction of 'base' name to be parts before *first* period
- Changed unit test to use 'Something.html.ftl'
25698: IE7 bug fix (a comma sign had slipped in by mistake)
25701: Continued implementation of ALF-7230. Bootstrap data amendments and additions for Team.
This changes the name of DataDictionary/EmailTemplates/NotifyEmailTemplates/notify_user_email.ftl to .../notify_user_email.ftl.sample.
With this check-in there will now be no .ftl files available for the Rules UI's "send email" action. The "Use Template" dropdown will have no contents. A future check-in will add the new (i18n'd) ftl files.
25702: Adds options support to Alfresco.widget.Resizer & updates console and calendar templates to use it. Tweaks styling on calendar to make it behave.
25703: Update the FileFolder localised version tests to do both Standard.html/Standard_fr.html and Another.get.html.ftl/Another_fr.get.html.ftl so we test both cases
25704: Provide a util helper for building Share and Alfresco (Explorer) urls up from SysAdminParams
25705: ALF-6628TR23: Preview support for Flash Video and HTML5 video.
- Customisable plugin architecture added for web-preview component, ootb plugins are:
* WebPreviewer: for documents (and image & flash movies) in other words the "good ol previewer"
* FlashFox: .mp4 & .flv videos for users w FlashPlayer 9
* StrobeMediaPlayer: .mp4 & .flv videos for users w FlashPlayer 10
* Video: HTML5 <video> element, support depends on the browser, but if youre lucky it might support .webm & .ogv movies
* Image: Displays images using the <img> tag (if taken from the nodes content and the image is larger than 0.5 mb, a link must be clicked to get the conten displayed).
* Flash: embeds flash content using swf-object
* plugin kicks in depending on node's mimeTYpe & thumbnail in combination w rules defined in web-preview.get.config.xml
- Added new mime types to repo:"video/ogg", "audio/ogg", "application/ogg" & "video/webm"
25706: ALF-6628TR23: Preview support for Flash Video and HTML5 video. part 2
- some strange white space characters had made their way in 25705
25708: Add new notifyPerson method to the Person service. This sends an email to the newly added user telling them their credentials, where to log in etc.
(Email template patch to follow)
25709: Use the new user notification method on the Person Service if requested, through the user CSV upload and person script service. It is on by default for CSV uploads, and off by default for javascript (Share)
25710: Add security file missing from earlier PersonService.notifyPerson checkin
25711: Further impl of ALF-7230.
Ensuring that the (recently renamed) notify_user_email.ftl.sample file has a qname path which is .sample-based.
25712: ALF-6835, ALF-7093 - Various improvements to Admin Console related to showing appropriate components based on license edition and admin console tool groupings.
- JMX tools now only available when an appropriate Enterprise license is found
- Subset of JMX tools available for TEAM edition
25713: Library updates for rev 25712
25719: Fix Alfresco.util.DataTable first request after r25693. Slight tweak to console tools list CSS for readability. Also modify how item separators work in social panel.
25722: Fixes broken links in wiki page within Team sample site
25732: Added quicktime move to the list of supported previews
25733: Added localised model title and descriptions for all the cm:person properties
25735: Revert non-English message bundles
25736: Document Library folders defaulted to visible on first use.
25739: Workaround for exceptions during bootstrap of clean db.
Changes to the email template acp introduced an exception. The changes are related to ALF-7230.
25740: Added read-write locking around veto code
25741: Patches runAs 'System' to allow execution even in read-only environment
25742: Patches runAs 'System' to allow execution even in read-only environment
25743: Removed some javadoc-style comments within methods
25744: Enhanced usage GET method
- Currently, I have problems preventing real data from being returned; so see dummy data
- Made usage GET a guest operation
- Included 'level', 'warnings' and 'errors'; see usage.get.desc.xml.
25745: Fix typo in error message
25748: ALF-7094: TR24: JSF-based login screens should warn unsupported when in Team mode (final text from Linton/docs)
25749: Make an unrestricted license available in the build classpath of each version
25750: ALF-6622 "Comment component redesign and refactor"
- Current user's avatar is displaye in add comment
- editor is correctly configured and styled and uses full width
25751: ALF-6602 - Final drag'n'drop icons and text from Linton/docs.
25752: Email templates for new user notifications, and a patch for this (applicable to both new and existing installs)
Note - acp may need a refresh later for tweaked templates, and description tweaks, but it shouldn't be a problem for anyone who gets this version now
25753: Reduced property path console logging on startup
25755: More acp hacking for ALF-7230.
Now the property key is defined in bootstrap-spaces.properties. Oops. Mustn't forget that next time.
25756: Update the User CSV scripts to use the new titles and descriptions for the person model, in both the template, and in the upload when skipping over title rows
25757: Tweak the User CSV upload template to show the descriptions properly in all excel versions
25758: Usage messages for usage web scripts
- Fixed unit test fallout
- Added license timeout as a restriction/usage element
25759: Fix for making "poster" attribute to videos understand the filesuffix of a thumbnail
25761: Fixed template to remove redundant 'warnings'
25762: Add a note about why this class generates mail text itself, via dedicated template service calls, instead of following the new pattern of passing a template noderef + model to the Mail Action Executor
25763: Update the site invitation mail action to enable the use of localised email templates (where present), and update to the new noderef+model pattern (rather than processing the template in the class)
25764: Fixed bug where it was only possible to upload a new version once on the docuemnt detais page, also small css tweaking in the version list
25765: Fix for ALF-7337 Email with content shorter than 5 chars causes exception in MailActionExecuter.
A simple fix that tightens up some string comparison.
25766: JMX MBean error handling: UI now shows the error message returned from the form processor. As the raw error message is being shown I have also localised the error messages on the server.
25768: Sample site users are now loaded in a disabled state so they do not count towards the user count. The main wiki page also had a broken link to one of the images in the project library which is now fixed.
25771: Removed organization id from the CSV upload as it's not used anywhere in the UI
25772: Added protection for the usage.users or usage.documents properties being null
25775: Removed unused warning suppress
25776: Minor formatting
25777: Added ability to get transactions that don't respect read-only vetos
- Typically used by doing
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
txnHelper.setForceWritable(true);
...
- This ranks with the 'Run As System' for permissions, but allows a clean separation between permissions and transactions.
- Don't have to force everything to run as 'System' to get a writable transaction, but 'System' will still have one.
- ALF-7236 RTEAM 34: Reload Licence fallout
- ALF-7256: Ensure license reload does not damage server after upgrades
25778: Allow patches to run against read-only system
- Made a write-forcing RetryingTransactionHelper available for patches and their offspring worker threads
- main upgrade thread is already running as 'System' user
- ALF-7236 RTEAM 34: Reload Licence fallout
- ALF-7256: Ensure license reload does not damage server after upgrades
25779: ALF-7257: Changed read-only setting to server.allowWrite to avoid mixing with Spring config
25780: Further impl of ALF-7230.
This check-in includes a patch which bootstraps a .html.ftl notification email template and placeholder templates for supported locales es, fr, de, it. (The notification email has a broken link in it. I will fix that today.)
25781: Inbound Email admin console tool disabled for Team edition
25782: Agenda View style fixes, non-default theme updates and description expand.
25784: Added MBean form config for the IMAP susbystem.
25786: ALF-6635 - Added IMAP admin console component
ALF-6835 - License component improvements
25790: ALF-6835 - Show license info warnings/errors. Show SysAdmin JMX console component so share host/port can be set for email templates.
25791: Build fix for recent changes (labels being added, scripts being renamed and site membership URL cleanup)
25794: Add missing admin user exclude to the people export with a site
25795: Further impl of ALF-7230.
Added a new acp containing a new example JavaScript file & a patch to bootstrap it in.
25796: Removing unnecessary property values. As part of ALF-7230.
25799: Improved the order of the fields in the sysAdmin MBean form, fixed typos in a couple of labels and provided more explicit labels (there were 2 fields each called Context, Host, Port and Protocol)
25800: Removed the loading of the command-*.js files that end up in Data Dictionary/Scripts. If they turn out to be required by something (we can't find any code reference to them anywhere) then they will need to be added back but to a different location.
25802: ALF-6884 "TR25: Reload license file on live server via JMX operation on LicenseDescriptor mbean."
25804: Agenda View polishing: Style tweaks, removed refresh jump, added "Today" button (currently uses page refresh), new Sketch icon, etc.
25805: Fix up license admin component after previous checkin
25806: Update the new user email template acp to have localised descriptions for the templates
25808: ALF-6621 "Version History panel"
- activitiy filed after new version upload
- fixed bug where revert didn't work
- components refresh inline instead of page reload
- made alfresco-macros.lib.ftl work when "page" attribute isn't present
25811: Update the site invite email templates to be localised and html. For new installs, you will get the html versions from the acp. For old installs, the text version will remain in DD, and you'll get (+ start using) the new html ones.
(Change also pushes some freemarker model logic from the people invite into template service, so the site import can use it.)
25812: For new installs, don't bootstrap load the old invite-email.ftl, as we now get the new html ones from an acp patch that always runs
25813: Merged V3.4-BUG-FIX to V3.4-TEAM (3.4.1 changes)
24884: adding back runBare over-ride - test was deadlocking
24894: Merged BRANCHES/V3.3 to BRANCHES/DEV/V3.4-BUG-FIX:
24892: Fix ALF-6729: Corrected build paths for WQS following upgrade of commons-pool library
24901: Fix ALF-6590: Requesting details of many assets using a GET request was causing Tomcat to close the socket connection. Changed so that we use a POST for this request.
24905: Merged V3.3 to V3.4-BUG-FIX
24904: Fixes ALF-5964: Installer height too small RHEL (records only)
24928: Merged V3.3 to V3.4-BUG-FIX
24927: Fixed ALF-5025 (ALF-6206): Support background processing of archiving
- Added property: xam.archive.forceBackgroundStoreMove=false
24930: Merged V3.3 to V3.4-BUG-FIX
24929: Merged DEV/DAVEW/SAP to V3.3
24925: ALF-6667: Fixed possible deadlock where index merger is never rescheduled under heavy load
24941: Merged BRANCHES/DEV/BRIAN/wqs-caching to BRANCHES/DEV/V3.4-BUG-FIX:
24613: WQS: Added caching layer for asset collections. Improves rendering time of homepage by 23% at steady state.
24944: ALF-6662 - Transfer/replication servers need to be compatible versions
25814: Convert the activities email templates patch/bootstrap from a single xml + classpath ftl, to an acp containing localised html versions following the new pattern
25815: Merged V3.4 to V3.4-TEAM (RECORD ONLY)
24946: Merged V3.4-BUG-FIX to V3.4 (RECORD ONLY)
24752: Merged V3.4 to V3.4-BUG-FIX
24751: Merged V3.3-BUG-FIX to V3.4 (RECORD ONLY)
Restored V3.3-BUG-FIX mergeinfo, somehow truncated in revision 24274
24757: Merged BRANCHES/V3.4 to BRANCHES/DEV/V3.4-BUG-FIX:
24756: Fix for ALF-6269: WebForm (Edit Web Content Wizard) ERROR on Alfresco Community Edition 3.4.b and 3.4.c
24771: Merged BRANCHES/V3.4 to BRANCHES/DEV/V3.4-BUG-FIX:
24767: Merged BRANCHES/V3.3 to BRANCHES/V3.4:
24765: ALF-6547: fix intermittent test failure (AssetServiceImplTest renameFile/renameFolder) - fallout from ALF-1948
24802: Merged BRANCHES/V3.4 to BRANCHES/DEV/V3.4-BUG-FIX:
24801: Fix for ALF-3055: "SecurityTestSuite hangs when run in DOD5015 context - failed authentication audit hangs on DB connection"
- do failed audits in a separate thread (from a thread pool)
24822: Merged BRANCHES/V3.4 to BRANCHES/DEV/V3.4-BUG-FIX:
24821: Fix for ALF-3055: "SecurityTestSuite hangs when run in DOD5015 context - failed authentication audit hangs on DB connection"
- fix up unit tests
24838: Merged BRANCHES/V3.4 to BRANCHES/DEV/V3.4-BUG-FIX:
24828: Merged BRANCHES/DEV/BELARUS/V3.4-2011_01_13 to BRANCHES/V3.4:
24824: ALF-6361: web-client-config-custom.xml doesn't work in /alfresco/tomcat/shared/classes/alfresco/extension
24857: Merged V3.4 to V3.4-BUG-FIX
24853: Merged V3.3 to V3.4
24852: Fixed ALF-6573 "Incorrect name of subgroups on "Groups" page"
24858: Merged BRANCHES/V3.4 to BRANCHES/DEV/V3.4-BUG-FIX:
24750: Limit installer builds to 2 threads
24874: Merged V3.4 to V3.4-BUG-FIX
24948: Merged V3.4-BUG-FIX to V3.4
24718: Merged V3.3 to V3.4-BUG-FIX
24717: Fix ALF-5555: It is impossible to edit review date from record's details page
24719: Fix for ALF-6106: Error on Check In operation with % symbol (SPP)
24733: Better fix for ALF-6106: Error on Check In operation with % symbol
24734: Fix for ALF-6089: Incorrect order of fields at 'Create Series', 'Create Category' and 'Create Folder' forms
The name, title and description fields are now placed in their own group on the server, all other non custom rm fields are put in an 'other' group, the client side config then declares a set for each group and orders them appropriately.
24753: Merged V3.3-BUG-FIX to V3.4-BUG-FIX
23870: Merge Dev to V3.3_BUG_FIX
ALF-4243: F5 load-balancer sending regular HTTP requests to Alfresco server causing Faces Servlet to throw java.lang.NullPointerException (MyFaces upgrade to from 1.1.5 to 1.1.7)
23897: Additional fixes and tweaks since introduction of MyFaces 1.1.7 library.
23919: More JSF component id related fixes.
23945: More MyFaces1.1.7 JSF page fix ups
23959: Another MyFaces 1.1.7 dup id issue fixed.
24008: ALF-4243
- Upgraded MyFaces from 1.1.7 to 1.1.8 to fix a bug seen in 1.1.7
- Added handling for the fact that valuebound properties that result in null now cause an exception where-as they were perfectly valid in 1.1.5.
24419: Merge from V3.3 to V3.3-BUG-FIX
r.24418 Fix for ALF-6075. Running out of /tmp space on the server is causing uploads to fail.
24768: Fixes ALF-6295: Allows MySQL to not be installed via unattended installer invocation
24779: Merge V3.3 to V3.4-BUG-FIX
24497 : ALF-3092 - deployment service - catch Throwable from Begin.
24684 : Merge DEV/BELARUS/V3.3-BUG-FIX-2010_10_04 to V3.3
23498 : ALF-5498 In Windows XP, placing a Folder with a Name that already Exists Removes all Content of the Existing Folder
24749 : ALF-6174 - Transfer Service fails with double peer assoc custom content type
24766 : ALF-5603 - It is impossible to assign workflow from workflow console to non-admin user
24812: Fix ALF-6316: A new "spoof" multivalue text property (cm:tagScopeSummary) is now made available for TagScope nodes when accessed via the getProperty or getProperties operations on the standard node service. The values of this property take the form "<tagname>=<tagcount>". A new interceptor has been added to the node service to do this (TagScopePropertyMethodInterceptor). WQS has been tweaked to make use of this new property, and the now defunct behaviour has been removed.
24820: Work in progress refactoring transaction handling of transfer unit tests.
24834: ALF-6468 - Update the scheduled actions folder bootstrap to use localisable names and descriptions, following the normal pattern
24836: Added system property 'system.cache.disableImmutableSharedCaches' (false by default)
- Equivalent to disabling Hibernate L2 cache for *immutable* entities
- Allows distinction between mutable and immutable cache entries
24850: Fix ALF-6562: Moved property that is used to label the WQS dashlet on the "configure site dashboard" page out of the Slingshot project and into the WQS Share Module project. Corrected its value to "Web Quick Start" rather than "WCM Quick Start".
24860: ALF-6673 - bootstrap folders and rename
24870: Removed svn:mergeinfo from root
24873: Merged V3.3 to V3.4-BUG-FIX (RECORD ONLY)
21789: ALF-4333: Fix
- Updated RepoPrimaryManifestProcessorImpl so it can handle deletions that are reported by either pre-delete noderef or archived noderef (previously only handled the latter).
- Updated TransferManifestNodeFactory so that it handles the case where the status of the node to transfer is "deleted".
- Updated UnitTestTransferManifestNodeFactory so that it handles the change to TransferManifestNodeFactory above.
- Added new tests for deletion cases.
23259: Merged HEAD to V3.3
23256: Fix ALF-4573: Start Workflow action is absent for edited document and working copy in Share
23346: Brought WebQS module in (including build process but not installer elements yet)
23371: "Simply" added wcmqs to installer
23391: ALF-5367: Copy dlls into tomcat/bin as appropriate.
23485: Merged V3.4 to V3.3 (fix backported for V3.3.x lines)
23472: Fixed ALF-5408: SQL Server missing ON DELETE CASCADE declarations
23515: Merged PATCHES/V3.2.0 to V3.3
23514: ALF-5554: Merged HEAD to V3.2.0
23153: When updating tag scopes following system shutdown/restore, be smarter about quickly skipping tag scopes that another (new) thread is currently working on
23283: More debugging level logging for tagging updates, to help identify the problem with periodic multi-threaded test failures on bamboo
23535: Merged V3.4 to V3.3 (complements 23517: ALF-5552)
23508: Fixed ALF-5559: Permission interceptors can fail if Lucene returns invalid NodeRefs
23564: ALF-5600: Merged V3.4 to V3.3
23424: Fixes: ALF-2989 - Incorrect sideId reference in URL for event in Site Calendar Dashlet
Adds support for displaying events that start in the past but finish in the future (previously only events that start in the future were shown)
23586: MERGED V3.4 to V3.3
22864: Fix for ALF-5005: "Create and edit functions on AWE become "confused""
23042: Fix ALF-5127: Impossible to create an article/blog (WCMQS) [Must clear panel hideEvent handler if manually hiding a YUI panel]
23561: Fixes: ALF-4569 - Removes universal override of input width box and switches the editor form panel to adjust it's width based on content rather than window size.
Fixes: ALF-4570 - Adds an override for the CSS 'top' property of the form dialogue to ensure it's always below the ribbon. (Was being set automatically by the YUI widget.panel call)
23569: Fixes: ALF-5606 - Ribbon wasn't resizing correctly after the form events.
23630: Backport of installer
23631: Added 64-bit & deployment installers
23664: Fixes ALF-5691: TransferService: Multi-byte characters are not encoded correctly
23681: Fixes ALF-5699: TransferService: Snapshot file from source repo never contains complete MLText properties
23695: Fixed bug exposed after fixing ALF-5699. Parsing of MLText properties out of the transfer snapshot file was incorrect, and that was causing multi-lingual property values to be duplicated
23709: ALF-5699: Fix NPE in ManifestIntegrationTest
23734: Merged V3.4 to V3.3
23731: Fixes for ALF-3098 and ALF-3097
- Share - Security check on Personal Dashboard - only the owning user can view a user dashboard page
- Share - Security issue on Customize Site Dashboard - private and moderated site dashboard pages no longer visible to non-members, customise site and dashboard pages only accessible to SiteManager
23747: ALF-5696: Merged V3.4 to V3.3
23585: Fixed ALF-5372 "JavaScript error on Groups management dialog with IE8 : document.getElementById is null"
23790: Fixed ALF-3823 "Share: RSS feed can't be read: http://cds-srv.sun.com:8700/rss/update/public/sunalert_update.xml - ok with other RSS client."
23883: Fixes ALF-5759: WQS: Attempt to copy a website section fails
23907: Merged DEV/BELARUS/V3.3-BUG-FIX-2010_09_20 to V33
22750: ALF-4846: Update rules are firing on inbound actions
23931: Undid rev 23907 (Reverse-merged /alfresco/BRANCHES/DEV/BELARUS/V3.3-BUG-FIX-2010_09_20:r22750)
23961: Fixed ALF-5686 "Incorrect behaviour of "All" filter in "My Tasks" dashlet"
- Variables assigned in a <#macro> shall always be assigned using <#local> (using <#assign> makes them globally available which might cause naming collisions)
24132: Disable intermittent failing unit test
24148: ALF-6007: Merged HEAD to V3.3
23049: Fixed ALF-5099: Error when trying to go back in Create Web Content Wizard (only with certain XSDs)
24263: Merged from V3.3-BUG-FIX to V3.3
24264: V3.3-BUG-FIX to V3.3
24262: Stress test code for ALF-5025: Support background processing of archiving
24287: Added missing import
24336: Merged V3.4 to V3.3
23205: Fix for ALF-2111 - Download URLS are different on different pages, authentication fails when URL sent
24353: Merged V3.4 to V3.3
24352: Fix SQL fallout from ALF-6078
24510: Merged V3.4 to V3.3
21960: First round of date refactoring: Document Library pages now expect XML dates (ISO8601) from Share data webscripts
21961: Share client-side I18N utility now emulates sever-side handling of doubled-up single quotes.
24526: Merged V3.4 to V3.3
24402: Fix for performance degredation related to ALF-3823.
RSS feed processing in JavaScript relies on Rhino impl of regex - this is extreemly slow as Rhino regex is by far the slowest component of the library.
Switched code to use the Java Regex libraries to improve performance and reduce memory usage.
24587: Merged V3.4 to V3.3
24564: Fix for ALF-3727: Custom permissions aren't visible in Explorer UI
24604: Merged V3.4 to V3.3
24602: Build fix for RM permission model loading - collateral damage for R 24564
24774: Merged BRANCHES/V3.4 to BRANCHES/V3.3:
23492: Fixed ALF-5550: DB2: Unable to insert values into alf_string_value
24813: Merged BRANCHES/V3.4 to BRANCHES/V3.3:
24750: Limit installer builds to 2 threads
24880: Merged V3.3 to V3.4-BUG-FIX
24463: Fixed ALF-4398 "Path to rule set is not displayed" ($html alias was missing from a merge)
24465: Merge V3.3 to V3.4 (RECORD ONLY)
24463: Fixed ALF-4398 "Path to rule set is not displayed" ($html alias was missing from a merge)
24493: Fix for Mac OS X CIFS logon problem, change UID to start at one as zero has special meaning, plus other minor fixes. JLAN-112.
24569: Fix for ALF-5333: Webdav - Online editing of files in a folder with German umlauts does not report correct characters
24611: Fix broken build due to merge #fail (r24460 / ALF-4015)
24668: ALF-4557 - Upgrade of large repository to latest 3.3 fails on excession of mysql table lock size
24707: Fix for handling of null first/last name in wiki page list
24710: ALF-5535 - Fix to correctly format json number values (not as numeric human readable strings)
24794: Fix for ALF-4984 - Outdated custom-slingshot-application-context.xml.sample file for share
24798: Fix for ALF-5806: Lucene query does not return expected result.
- Alfresco FTS now supports the prefixes ~ and = for phrase queries
24814: Build fix after r24798: Fix for ALF-5806: Lucene query does not return expected result.
24823: Synchronization improvements to RemoteClient and http proxy hosts
24825: Fixed #3 of ALF-6308 "Share data issues"
- Share falls back to use "html uploader" (in all browsers except IE) when "JSESSIONID" cookie is unreachable from javascript (like when "HttpOnly cookies" is activated on the server.
24835: Fixed ALF-5484: Check-in does not update association
- Copy code when copying over an existing target node was NOT processing associations
- Fallout from refactor and subsequent fixes related to ALF-958 (Target associations aren't copied)
- Some commented-out unit tests reintroduced
24842: Fix for ALF-6308 item #4 - validate the redirect URL to ensure it is a relative url
24845: Merged DEV/DAVEW/SAP to V3.3
23874: ALF-5822: Correct Lucene throttling mechanism to prevent build up of excessive committed deltas
- Also correct BatchProcessor's mechanism for single-threading batches with cross dependencies
- Single-threaded batches must be sequenced in order
23876: ALF-5822: Default lucene.indexer.mergerTargetOverlaysBlockingFactor to 2 for better write performance under load
24022: ALF-5822: Refinement of fix
- Don't block a thread that has already entered the prepare phase with another indexer (e.g. a cross-store commit). Otherwise it could block indefinitely and never enter the commit phase
- Also added extra debug diagnostics and handle all Throwables on failure
24023: ALF-5822: Minor correction to debug log message
24421: ALF-6134: Do not export org.hibernate.jmx.StatisticsService through JMX to avoid excessive blocking under load
24422: ALF-6135: Remove lock contention from concurrent Lucene searches
- Added a RW Lock and Thread local-based solution to org.apache.lucene.store.FSDirectory.FSIndexInput.readInternal() to avoid contention during multiple parallel Lucene searches. This is already recognized as a bottleneck by the Lucene developers, who offer NIOFSDirectory as an alternative, which unfortunately doesn't work on Windows.
- Added RW lock to org.apache.lucene.index.TermInfosReader.ensureIndexIsRead()
- Threads no longer hanging in lucene searches during load tests. Woohoo!
24423: ALF-6136: Don't call through to org.apache.log4j.NDC unless debug is enabled as it's heavily synchronized. Also avoid dynamic method invocation by using a delegate.
24426: ALF-6138 (SURF - PARTIAL): 'Warm' the java.beans.Introspector cache for key Freemarker accessible bean classes on loading in static initializers
24428: ALF-6139 (SURF - PARTIAL): First log in to Share is expensive due to 'lazy' dashboard creation and excessive synchronization
- Added AVMRemoteStore.createDocuments() for creating multiple XML documents at once, all embedded within the same master XML document in the request body
- Added corresponding saveDocuments() methods to Store, RemoteStore, Model, ModelObjectManager and ModelObjectPersister on the Surf side
- Used this in PresetsManager
- Removed excessive synchronization from StoreModelObjectPersister
24429: ALF-6140 (SURF - PARTIAL): Surf tweaks to allow concurrent execution of web scripts
- Use StrongCacheStorage instead of MruCacheStorage in RepositoryTemplateProcessor to avoid use of a synchronized cache
- Tweak cache sizes in FreeMarkerProcessor
- Use thread local object wrapper delegates in QNameAwareObjectWrapper and PresentationTemplateProcessor to work around synchronization in DefaultObjectWrapper
- Swap in the same object wrapper to WrappingTemplateModel
- Use a concurrent HashMap in ModelObjectCache and ModelHelper and remove excessive synchronization
- Use RW locks rather than synchronized blocks in AbstractWebScript
24431: ALF-6141: Improvements to IBatis DAO performance under load
- Use lazyLoadingEnabled="false", enhancementEnabled="false" to avoid unnecessary blocking and generation of CGI proxies in IBATIS DAOs
- Use useTransactionAwareDataSource="false" to prevent Spring from agressively unwrapping DBCP connections and bypassing the prepared statement cache
24432: ALF-6142: Remove dependency between RepositoryAuthenticationDAO and Lucene
- Reworked RepositoryAuthenticationDAO to use a node service lookup by child association QName
- This required adding a patch to 'upgrade' the qnames of existing authentication nodes, which previously all had the same QName
24433: ALF-6143: Remove net.sf.ehcache.use.classic.lru setting from EhCacheManagerFactoryBean and InternalEhCacheManagerFactoryBean to prevent serialization of accesses to shared caches by multiple executing threads
24434: ALF-6144: DirtySessionMethodInterceptor was causing contention between multiple threads calling the same DAO.
- Unfortunately method.getAnnotation() is a synchronized call, and thus causes concurrent calls to the same method to contended with each other.
- Added a non-blocking cache so that DAOs can be accessed in multiple threads without contending.
24435: ALF-6145: Use RW Locks in Subsystem Framework
- The operations relied on by the dynamic proxies wrapping subsystems were synchronized and thus caused contention when multiple threads were calling in to the same subsystem
- Replaced synchronized blocks with use of read write locks, thus allowing multiple concurrent readers
24436: ALF-6146: Regulate PermissionModel accesses with RW locks, rather than synchronized blocks and an excessive number of concurrent hashmaps.
24438: ALF-6136: Fix build classpath
24439: ALF-6142: Fixed seeding of admin user password
24444: ALF-6142: Fix unit test fallout
- InviteServiceTest needs a transaction
- RepositoryAuthenticationDao must listen for Person username changes and update authentication node qname accordingly
- Correction to MT handling in RepositoryAuthenticationDao
- Repository Authentication Component must 'normalize' the username before passing it through the DAO
24445: ALF-6145: Correction to lock handling when propagating destroy() events
24446: ALF-6142: Add new dependencies to unit test
24448: ALF-6142: Further fix ups
24461: ALF-6142: Fix unit test
24664: ALF-6408: Prevent possible deadlock during reindexing
- waitForHeadOfQueue() now only called in beforeCommit() phase rather than afterCommit() to prevent deadlocking with Lucene throttler
- indexes are also flushed beforehand in beforeCommit() so that indexing work can still be parallelized
- also prevent potential deadlock caused by clearing of IndexInfo.thisThreadPreparing in a nested transaction
24810: ALF-6653: Use read write lock in Hibernate ReadWriteCache to avoid needless contention on L2 cache reads
24817: ALF-4725: Avoid excessive lock contention in dbcp by upgrading to 1.4
- also upgraded commons pool
24818: ALF-6658: Remove synchronization from LockService - transaction local collections used anyway
24844: ALF-6681: Don't let the PostLookup job stack up in multiple threads
- Now only executes in one thread at a time and skips scheduled slots where it is already running
24864: Fix for ALF-5904: Explorer - Space model rights not duplicated when creating a space based on a template
- copy service no longer uses hasPermission
- added tests for permission copy scenarios with assorted rights
- this fix assumed there is nothing special about templates - ie that they should always carry permissions and is the "default" copy behaviour to copy permissions if possible
24865: ALF-6145: Fix failing unit test
24878: ALF-6146: Correction to write lock around requiredPermissionsCache
24881: Increment version revision
24884: adding back runBare over-ride - test was deadlocking
24894: Merged BRANCHES/V3.3 to BRANCHES/DEV/V3.4-BUG-FIX:
24892: Fix ALF-6729: Corrected build paths for WQS following upgrade of commons-pool library
24898: Fixed merge issue in FixUserQNamesPatch
24901: Fix ALF-6590: Requesting details of many assets using a GET request was causing Tomcat to close the socket connection. Changed so that we use a POST for this request.
24905: Merged V3.3 to V3.4-BUG-FIX
24904: Fixes ALF-5964: Installer height too small RHEL (records only)
24928: Merged V3.3 to V3.4-BUG-FIX
24927: Fixed ALF-5025 (ALF-6206): Support background processing of archiving
- Added property: xam.archive.forceBackgroundStoreMove=false
24930: Merged V3.3 to V3.4-BUG-FIX
24929: Merged DEV/DAVEW/SAP to V3.3
24925: ALF-6667: Fixed possible deadlock where index merger is never rescheduled under heavy load
24941: Merged BRANCHES/DEV/BRIAN/wqs-caching to BRANCHES/DEV/V3.4-BUG-FIX:
24613: WQS: Added caching layer for asset collections. Improves rendering time of homepage by 23% at steady state.
24944: ALF-6662 - Transfer/replication servers need to be compatible versions
25816: Removed unused config files; superceded by subsystem configuration
25817: Tweak how the html notification/invite template ACPs are patched/bootstrapped to better fit the pre-existing pattern
25819: ALF-7230. Fixed the document link sent out in the notification email.
This document link is now a Share link and requires the admin to have configured SysAdminParams with server config data such as port number etc.
Added the SysAdminParams bean to the ServiceRegistry
Added a helper method to TemplateNode to get the Share URL for a (document) node.
Updated the email templates within the acp to use the helper method in TemplateNode.
25820: Merged V3.4 to V3.4-TEAM
24885: Fix ALF-6694: V3.4.0 schema inconsistencies
- ALF-6712: DB2: alf_authority missing index 'authority' during upgrade
- ALF-6714: ALL: alf_prop_unique_ctx missing FK index on upgrade from 3.3 and 3.2
24889: Disabled intermittently failing test (ALF-6700) until it can be made more reliable.
24951: Merged DEV/DAVEW/SAP to V3.4
24950: ALF-6698: Allow clearBatchSize and updateBatchSize properties of userUsageTrackingComponent to be controlled through system.usages.clearBatchSize and system.usages.updateBatchSize global properties
24966: Fixed ALF-6363: Transaction status incorrect during afterCommit phase
- Covered by unit tests
- afterCommit or afterRollback will report "Not in transaction"
24969: Fixed ALF-4372: JavaDocs don't match code for Index Recovery Modes (VALIDATE)
24970: WQS: Fixed web publishing transfer service Spring definition (hopefully permanently now) following change to TransferService requirements
24974: Fix ALF-6813: WQS: Specifying the sort order in the query of a dynamic asset collection has no effect
24978: WebDAV: minor debug logging fixes
- fix WebDAVHelper logger name to be consistent (with rest of WebDAV and other filesys protocols)
- log service call as info (separate from rest of debug)
24983: Step 1 of ALF-3891: Policy beforeDeleteChildAssociation not fired on delete node
- Clean up deprecated beforeCreateChildAssociation, which could only be used *after* the event
24985: Attempt to fix ALF-6820: Slow CMIS unit tests on build box
24994: Fixes: ALF-6815 - terminology change (also fixes encoding bug that was preventing files being loaded into translation memory)
24995: ALF-6572 - WCM: virt svr - enable "lazyDeploy" by default
- can be disabled (in server.xml)
24997: correction/kludge of DescriptorServiceTest.
25002: Fix up test.
25029: Merged DEV to V3.4
25009: ALF-5829: Cannot upload files to Records Management site using WebDav from Mac OS X
- Configuration constant that maps User-Agent pattern to response status code was added to WebDAVMethod.
- Method that determines response status for AccessDeniedExeption using ‘User-Agent’ header was added.
- AccessDeniedException processing was changed to return appropriate status.
25043: Merged DEV to V3.4
25012: ALF-6758: Potential JGroups Locking issue requiring jgroups upgrade
JGroups was upgraded to the latest available stable version 2.11.1 Final:
- jar was upgraded;
- sources were upgraded;
- classpath of the ‘3rd Party’ project was upgraded;
- AlfrescoJGroupsChannelFactory was upgraded according to extension in superclass
25061: Merged DEV to V3.4
24920: ALF-1787: Slow performances when many workflow are opened
1. Implementation of a custom query for JBPMEngine.getAssignedTasks.
2. Uint test for creating and testing neccessary items in DB.
25014: ALF-1787: Slow performances when many workflow are opened
1. HQL query for TaskInstance properties chache.
Also:
- Moved back to query.list() - no difference with scroll
- Checked query plan for batching queries and found no problems
- Batch queries *have* to be limited in the IN clause
- Although not using scrolling, there was a missing close statement
25072: Reversed change 25043: Slow performances when many workflow are opened
25094: Resolve ALF-6736: CMIS Web Services: getObjectByPath() should return an objectNotFound error if the given path doesn't exist
25107: Resolve ALF-6754: CMIS nameConstraintViolation errors are not returned to client
25122: Merged HEAD to BRANCHES/V3.4:
25115: Fixes: ALF-6336 - resolved incorrectly translated date formatting strings.
25144: ALF-6841 - IMAP Sync Errors
25148: ALF-6991: Connection pool causes poor performance in some test suites
- Added explicit 'forceMultipleResultSetSupport=false' in case someone wants to change it.
- This is not a fix (or actually a change at all) just a documentation of the options available
25149: Added transaction leak checks in security tests.
- Just helpful for diagnosis when one test fails and brings the others down.
25182: Merged PATCHES/V3.4.0 to V3.4
25180: Merged DEV/TEMPORARY to PATCHES/V3.4.0
25150: ALF-6918: Editing a Share document simultaneously using Share HTTP and Webdav breaks the document - working copy relationship.
User can't unlock and edit original node that was checked out by him.
WebDAVMethod-> checkNode() was changed to return Http Status 423 if node has a working copy
25181: Merged DEV/TEMPORARY to PATCHES/V3.4.0 (with corrections)
25102: ALF-6894: Share IMAP - Modifier and date/time incorrect.
ImapServiceImpl.checkForFlaggableAspect() method was modified to disable "auditable" behavior before adding "flaggable" aspect and then enable it again.
25193: Fix ALF-7039: Unable to specify target MIME type for renditions generated by the TemplateRenderingEngine
The "mime-type" parameter is now exposed by any rendering engine that is derived from the BaseTemplateRenderingEngine
25205: Merged V2.2 to V3.4
25184: ALF-6914: Use RetryingTransactionHelper in WorkspaceClipboardItem
- Also decoded the mysterious looping logic
25214: Merged BRANCHES/DEV/BELARUS/V3.4-2011_01_13 to BRANCHES/V3.4:
25045: ALF-6435: SPP doesn't work with MT users
25216: Merged HEAD to BRANCHES/V3.4:
25100: Fix for build issue Steve was encountering on new build boxes using Ant 1.8.x
25219: Fix for ALF-6312: "Incorrect work of AWE functionality"
25222: Merged BRANCHES/DEV/BELARUS/V3.3-2010_12_20 to BRANCHES/V3.4:
24943: ALF-6103: Explorer - Version type not set by auto version
25224: Fixed ALF-6992: PersonUsagePatch is sequenced incorrectly and is too slow
- Added direct SQL update for cm:sizeCurrent (adds a type NULL property just like the Java patch did)
- Removed the Java patch; ensured that new patch has the old as an 'alternative' and that the old patch is now a NoOp.
- Tested with 50K users upgrading from 2.1
- Can be backported safely to 3.2 and later.
- Will provide instructions in the JIRA for working around.
25225:ALF-6992: PersonUsagePatch
- Fixed alf_applied_patch entry
25229: Fix for ALF-6661: Fixed issue with navigation handling in JSF client, although seen via WebDAV in the bug description, it's actually the same for any inline editing.
25237: Fix for ALF-6463: Collaborator and Editor cannot rename items via WebDav
25244: Fix for ALF-6858: Uninitialized FormUI options parameter causes UI to be unusable
25245: A new schema version range for 3.4.1
25246: Merged BRANCHES/DEV/BELARUS/V3.4-2011_01_13 to BRANCHES/V3.4:
25226: ALF-6348: Edit the event to reccurent and backward doesn't work
25253: ALF-7059: Excessive webscript loading times in v3.3 and v3.4
- Corrected escaping of Lucene document searches in RepoStore
- The '-' character was getting interpreted as an operator when searching for package-desc.xml
25256: ALF-5143: Eliminate use of non-I18N friendly FileWriter
25258: Undid fix for ALF-6992 revs 25224 and 25225
25259: Fixed ALF-6992: PersonUsagePatch is sequenced incorrectly and is too slow
- Fixes ALF-6954, too: CLONE - Attempt to login into Alfresco fails for previously created users ...
- Follows previous fix removal
- Moved SQL from bootstrap to patch execution, but still do a mass update
- Ensure that QNames are present prior to SQL execution
- 'patch.authorityDefaultZonesPatch' depends on 'patch.personUsagePatch'
25261: Merged DEV to V3.4
25160: ALF-1787: Slow performances when many workflow are opened
1. Implementation of a custom query for JBPMEngine.getAssignedTasks.
2. Uint test for creating and testing neccessary items in DB.
3. HQL query for TaskInstance properties chache.
4. HQL query for ContextInstance variables chache.
25270: Fix for ALF-6271. ThumbnailRegistry loading definitions without transaction.
25275: Merged DEV to V3.4
25243: ALF-6583: when a LDAP admin removes its own account, account cannot be useed anymore and cannot be recreated
- Full path to node calculating logic was extracted from ‘org.alfresco.filesys.repo.NodeMonitor.beforeDeleteNode()’ policy handler:
- ‘NodeMonitor’ performs lookup operations as 'System' user
25251: ALF-6583: when a LDAP admin removes its own account, account cannot be useed anymore and cannot be recreated
- Additional persons’ cache controlling was added:
- currently, ‘org.alfresco.repo.security.person.PersonServiceImpl.getPersonOrNull()’ checks all ‘User Home’ NodeRefs before using;
- all inexistent NodeRefs will be removed from the cache
25281: Attempt to prevent build hang in ChainingUserRegistrySynchronizer
25287: Merged DEV/TEMPORARY to V3.4 (with correction)
25284: ALF-5596: Alfresco WebDAV does not work when repository is in read only mode.
25295: Merged DEV/DAVEW/SAP to V3.4
25207: ALF-6856: Avoid checkout failures under heavy load
- Stop absorbing all exceptions in checkin / checkout / cancel-checkout
- Propagate object wrapping code, message and cause instead
25208: ALF-7062: Use a shared cache in RepositoryAuthenticationDao
25209: ALF-7063: Use nodeService.exists() instead of a Lucene search in Search.findNode()
25210: ALF-7064: Use caching plus a read write lock to avoid contention in SubsystemChainingAuthenticationService under load
25211: ALF-7065: Use cached authorityService.getContainingAuthorities() method to improve performance of SiteServiceImpl.getPermissionGroups()
25220: ALF-7062: MT fix
25221: ALF-7062: Fix AuthenticationTest
25223: ALF-7065: Refinement to use of cached authorities in SiteServiceImpl.getPermissionGroups() that preserves current 'direct memberships take precedence' semantics.
- First fetch cached recursive group memberships. If there are zero or one, they can be returned immediately.
- Otherwise, fetch immediate group memberships and work it out from there.
25230: Extend ehcache cluster sample with socketTimeoutMillis=10000. Increase timeout from its 1 second default to avoid lots of RMI and cache integrity errors under load.
25297: Fixed merge issue in 25295
25302: ALF-6067: Unable to run read-only server without error
- The latest error could not be reproduced
- Added double-check to bypass audit if the system is in read-only mode (TransactionService.getAllowWrite())
25306: ALF-5596: Merged DEV/BM to V3.4
24726: BM - tweak WebDAV propfind (to use read-only txn)
25326: Fixes for DB coverage: ALF-1787: Slow performances when many workflow are opened
- Refactored query to use neat JOIN syntax
- Added back batch size limiting to prevent Oracle blow-outs
- Added in parameters to cover boolean query conditions
25334: Added missing quotes in invitation service properties file
25336: Merged V3.3 to V3.4:
- 24918: ALF-6496: Browsing large File Plan is slow
- 24940: - Fix up issue with over enthusiastic caching of capability results.
- Rename troublesome capability test so as not to hold up the build.
- 24947: Fix-up to capabilities test.
- 24973: Unit test fixes
- 25046: Build fixes
- 25080: RM: Fix transaction cache key
- 25260: ALF-7000: RM: Cuttoff action for folder is missing when record is frozen
25344: Updated capability tests. More to come.
25370: Fix for ALF-3339 - Modifying the properties of a link on a Folder does not show up after pressing the OK button but after pressing the 'close' button
25374: Fix for ALF-6691 - Incorrect behavior of RSS feed for Wiki. Also fixes other minor RSS feed validation issues (pubdate format).
25389: RM: Build fixes
25414: Fix for ALF-3202: ALL field not fully implemented in LuceneQueryParser for wildcards, prefixes, and fuzzy
- all current fields behave sensibly or throw unsupported
25424: Fix for ALF-6576 - Search by tags shows not empty results on the site which has no content
25467: Resolve ALF-7074: CMIS web services do not appear to allow ticket authentication
25508: Fix for ALF-7110 - JSF custom component Form submit value encoding
25538: ALF-6497: Updates to disposition schedules in progress do no complete with large record sets
- Updates to records under the control of an edited disposition schedule is now performed in the background
- A quartz job manages the record updates
- UI updates to show whether there is a unpublished update to the disposition action pending
25539: RM: Ensure not "all" behaviours are switched off when processing disposition action defintions updates.
- rm search information is now being populated and shown in the Ui correctly post publish
- see ALF-6497
25545: Merged V3.3 to V3.4
ALF-7196: Records only
25573: Deleted : /alfresco/BRANCHES/V3.4/root/modules/dod-5015/source/java/org/alfresco/module/org_alfresco_module_dod5015/model/FilePlanComponentAspectTest.java
25603: Updated Postrgresql install switch
25608: Fix Eclipse classpath after Postgres driver move
25620: Fix for escalated issue ALF-7218: Advanced Search in Share breaks with custom type which contains underscores in type name
25622: Merged BRANCHES/DEV/BELARUS/V3.4-2010_12_14 to BRANCHES/V3.4:
24647: ALF-6307: Compliance for Third Party jars with Source Modified
25623: ALF-6309: Changes to notice.txt and addition of license files
25627: Fixes ALF-7222: Updated linux installer window height (with taller image to hide additonal background)
25633: Fix intermittent unit test failure - retrying txn in RecordsManagementAuditServiceImplTest
25637: Merged DEV/TEMPORARY to V3.4
25215: ALF-6696 : Upgrade from 2.1.7 to 3.3.4 failing Due to "out of memory"
All large db scripts for all supported dialects was modified to follow batching approach.
25325: ALF-6696 : Upgrade from 2.1.7 to 3.3.4 failing Due to "out of memory"
1. Upgrade scripts for all supported dialects was corrected to follow mysql style after David's review of batching porting work.
25398: ALF-6696 : Upgrade from 2.1.7 to 3.3.4 failing Due to "out of memory"
Some errors was corrected in upgrade scripts after David's review.
25643: Initial commit of reworked Japanese language pack
25669: Merged BRANCHES/DEV/dwebster/ to BRANCHES/V3.4:
25665: Spanish Language Pack update from Gloria
25671: Updated installer with simple Easy install. Fixed binaries inclusion.
25684: Fixes: ALF-7102 - minor (consistent) typo in i18n string.
25692: ALF-7293 - Handle error condition of unsupported RSS XML format (RDF in this case)
25707: ALF-6993 Fixed AlfrescoTimer so that it no longer ends the task if the Timer is set to repeat.
25715: Fix intermittent failing unit test by increasing time window
25718: Merged PATCHES/V3.4.0 to V3.4
25700: Fix for ALF-7059: Webscripts: Startup: webscript loading takes about 10 minutes to complete.
- QNAME:simpleToken will go down an optimised route
25720: Fix for ALF-7318: patch.calendarNamespaceUri fails as the TYPE field no longer supports prefix queries
Part fix for ALF-6291: Inconsistencies in lucene search queries with wildcards and single letters.
25721: Fixed ALF-7319. Removed ';'.
25734: Updated copyright to 2011
25738: Fix to issue with groups display and wrong panel returned to after cancel group edit
25773: Merged BRANCHES/DEV/BELARUS/V3.4-2011_02_16 to BRANCHES/V3.4:
25747: ALF-6307 Compliance for Third Party jars with Source Modified
25798: Merged PATCHES/V3.4.0 to V3.4
25789: Merged DEV/TEMPORARY to PATCHES/V3.4.0
25783: ALF-7079: concurrent access to share site using the Share web UI and webdav by two users break the copy.
1. The WebDAV MOVE and DELETE methods were modified to properly handle the "MS Word shuffle" for working copies.
25793: Merged DEV/TEMPORARY to PATCHES/V3.4.0
25395: ALF-7079 : concurrent access to share site using the Share web UI and webdav by two users break the copy.
UnlockMethod (webdav) was modified to correctly handle working copies.
25803: Merged V3.3 to V3.4 (RECORD ONLY)
25015: ALF-6749: Merged V3.4 to V3.3
24601: Fix for ALF-6032: It's impossible to create meeting items
25062: Merged V3.4 to V3.3
25061: Merged DEV to V3.4
24920: ALF-1787: Slow performances when many workflow are opened
1. Implementation of a custom query for JBPMEngine.getAssignedTasks.
2. Uint test for creating and testing neccessary items in DB.
25014: ALF-1787: Slow performances when many workflow are opened
1. HQL query for TaskInstance properties chache.
Also:
- Moved back to query.list() - no difference with scroll
- Checked query plan for batching queries and found no problems
- Batch queries *have* to be limited in the IN clause
- Although not using scrolling, there was a missing close statement
25276: Merged V3.4 to V3.3
25261: Merged DEV to V3.4
25160: ALF-1787: Slow performances when many workflow are opened
1. Implementation of a custom query for JBPMEngine.getAssignedTasks.
2. Uint test for creating and testing neccessary items in DB.
3. HQL query for TaskInstance properties chache.
4. HQL query for ContextInstance variables chache.
25328: Merged V3.4 to V3.3
25326: Fixes for DB coverage: ALF-1787: Slow performances when many workflow are opened
- Refactored query to use neat JOIN syntax
- Added back batch size limiting to prevent Oracle blow-outs
- Added in parameters to cover boolean query conditions
25373: Merged HEAD to V3.3
25100: Fix for build issue Steve was encountering on new build boxes using Ant 1.8.x
25807: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/V3.4:
25785: Add the WQS client API to the "generate-javadoc" build target
25792: Fix ALF-7345: WQS: Unable to place a WQS on the root context of a web container easily. This fix enables the web context of a WQS website to be set to "/" to indicate that it lives at the root of the URI namespace of the web container.
25809: Merged V3.3 to V3.4
24899: (RECORD ONLY) Merged V3.4-BUG-FIX to V3.3
24898: Fixed merge issue in FixUserQNamesPatch
24913: Merged BRANCHES/DEV/BELARUS/V3.3-2010_12_20 to BRANCHES/V3.3:
24890: ALF-837 Firefox: Incorrect behaviour of Insert/Edit image option on creating content based on web form
24962: (RECORD ONLY) Merged PATCHES/V3.3.3 to V3.3
24959: ALF-6780: Merged V3.4 to PATCHES/V3.3.3
23385: Fix for ALF-5166: After restore of indexes - AUTO hangs
- bulk deletes are now handled as such during index tracking and rebuild (as they are normally)
25011: Attempt to resolve latest build deadlock: Specify inputstring="" in junit invocations in order to work around Ant bug https://issues.apache.org/bugzilla/show_bug.cgi?id=37887
25012: Reverse previous checkin.
25033: ALF-6535: Changes to enable session sticky sessions for SPP
25034: Merged DEV/TEMPORARY to V3.3
25026: ALF-6763 : Malformed web.xml prevents 3.3.5 340 JBoss deployment, org.apache.myfaces.ERROR_HANDLING param should be replaced
1. Web.xml was modified for web-client to allow bootstrap alfresco on Jboss EAP 5.1.0.
25060: (RECORD ONLY) ALF-6114: Rules for updated items are triggered before users commit any changes.
25063: Merged DEV/TEMPORARY to V3.3
25059: ALF-608 Errors when uploading content via CIFS result in zero byte files
Closing file operations wrapped by transaction in ContentDiskDriver.
Catching IOException in NTProtocolHandler.procCloseFile() was changed to catching Throwable to avoid delay.
25067: For for ALF-6807: TinyMCE: This is a follow up of: http://issues.alfresco.com/jira/browse/ALF-5420 (escalation)
25177: ALF-6855: Adding versionable aspect as rule in share site causes errors
25186: Merged PATCHES/V3.3.3 to V3.3
25065: Fix for ALF-6780 Full re index seems to not ends up under certain circumstances.
- A full rebuild only creates nodes
- Fixed issue repeating all previous deletes already processed in the transaction (for deletes and updates to nodes) with every delete/update in the transaction
- Closed TermDocs enumerations
25372: ALF-5933: Updated mysql collate encoding
25456: Fix for ALF-7078: CLONE -Impossible to reject invitation due to script error
25478: Fix for ALF-6756 - JSON delete should not pass body for request
25498: (RECORD ONLY) ALF-5964: Updated installer window height for linux
25533: ALF-6946: Correction to WAS libraries.xml
25558: (RECORD ONLY) Fixes ALF-6268
25560: Fixed ALF-7210: User workflow tasks query fails on RHEL
- Case-sensitivity in the table aliases cause failure on unix
- Must be 'processInstance' not 'processinstance'
- Fallout from ALF-1787: Slow performances when many workflow are opened
25810: Merged V3.3 to V3.4 (RECORD ONLY)
25070: Reversed revision 25062
25822: First embryo of social items on doc details page.
25823: ALF-7336 - License file to be loadable from configurable location
25824: ALF-7333: TR24: IMAP, CIFS, WebDAV & FTP should not mount company & user home by default
- Added global property 'protocols.rootPath' defaulting to protocols.rootPath=/${spaces.company_home.childname}
- Included 'protocols.rootPath' in file-servers config and IMAP config
- TODO: Get 'protocols.rootPath' into WebDAVServlet
25825: Fixed Eclipse classpath which contained a reference to someone's Tomcat directory
- To avoid having to update the classpath, create a project in Eclipse called "Enterprise Runner"
and pull in the "Enterprise Repository" into that. Then run tests in context of "Enterprise Runner".
Additional jars and paths can be pulled in as required.
25826: Merged V3.4 to V3.4-TEAM
25301: (RECORD ONLY) Merged V3.4-TEAM to V3.4
25189: Expose getAllowWrite on the TransactionService API
25821: ALF-5841 Applied fix to queryTasks() to stop the process definition hibernate query exceeding the limit of 1000 arguments.
25828: New i18n labels for social interactions
25830: Working "likes" added to document header on doc details page, using the Alfresco.Like widget found in share.js
25831: More work in progress ALF-6593: TR04: Update dashlets to provide consistent look & feel, include thumbnails, help text, action links where applicable
25832: Remove placeholder text (unused)
25833: Some improvements on the "likes" in share.js, such as calling it Alfresco.Like instead of Alfresco.Favourite... :-)
25835: Build fixes for RM related tests
25836: Added "favourite" on doc details page's header suing Alfresco.Favourite foun din share.js ALF-6614 "Page redesign and refactor"
25837: Update the new html templates - remove the share_or_team flag (switching to just being "Alfresco"), and rationalise on shareUrl rather than a mix of shareUrl and share_url
Also tweaks how shareUrl is injected into the model
25838: I have no idea why FormServiceImplTest is failing on the build server, it runs fine locally. In the interest of getting a successful build this weekend I'm disabling the failing checks until I have time to investigate the environment difference on the build server.
25839: Fixes to siteURL macro and param reader following recent refactoring.
25841: ALF-7358 - RTEAM 38: User count is not decremented when users are removed
ALF-7378 - RTEAM 39: Excess users error is not accurate for an end-user
25842: Removed deep permission checks in RepoUsageComponent
25844: Url fix for "like activity" posted from doc details page ALF-6614 "Page redesign and refactor" activities
25847: ALF-6614 "Page redesign and refactor" added missing peice "comments" in doc detail header
25848: Update the InviteSenderTest to work with the new way of passing the template details+model to the MailActionExecutor, rather than rendering the text itself
25856: Change the User CSV Upload webscript to handle the transaction itself. This means that if the transaction commit fails (eg user limit exceeded, custom person validation fails) then we get to send the client our own error message+status code.
(Previously the commit failure was trapped by RepositoryContainer, and so the webscript had no control over the error reporting process, which is required in this case to meet share UI needs)
25858: When generating WebScriptExceptions from a resource bundle (instead of the more usual system properties), ensure that the underlying cause (if present) is included
25864: Added back logging of subsystem start/stop.
25865: Removed unused code and comments
25871: General license fixes
- Apply forced read-write to transactions
- Heartbeat code synchronization around enable/disable
- Fixed license test to check for heartbeat state correctly
25872: Merged V3.4 to V3.4-TEAM
25849: Fixed ALF-7379: PostgreSQL patch.migrateAttrAVMLocks error when upgrading to Enterprise 3.4
- PostgreSQL doesn't accept column aliases without 'as'
- Probably version-dependent
25850: Merged BRANCHES/DEV/dwebster/ to BRANCHES/V3.4:
25843: Updated FR files received from Gloria 2011-02-25
25845: Updated IT files received from Gloria 2011-02-25
25846: Updated DE files received from Gloria 2011-02-25
25859: Merged PATCHES/V3.4.0 to V3.4
25857: ALF-7376: Detect concurrency problems in PutMethod
25867: Fixes: ALF-5628 - Meeting Workspace Calendar Entry issue.
25868: ALF-7274: Reinstate &characterEncoding=UTF-8 into default MySQL JDBC URL, using proper encoding of & for an XML file (&)
25882: License tests: Narrow down failures (doesn't fail locally) and also deal with logging problems
25883: ALF-6593: TR04: Update dashlets to provide consistent look & feel, include thumbnails, help text, action links where applicable.
New placeholder filetype icons @ 32x32.
New avatar get URL (internal): /slingshot/profile/avatar/{username} or /slingshot/profile/avatar/{username}/thumbnail/{thumbnailname}
Added "avatar32" thumbnail preset.
25885: Remove reference to non-existent file. Add folder icons back into path on the details page.
25886: Added new avatar photo placeholder icons from Linton
25893: Fixed Legal and License url in About dialog
25895: Fix for ALF-6622 "Comment component redesign and refactor"
* show new comments component where required
* comments in correct order
* displaying ok in 1024x768
25897: Fix for ALF-6622 "Comment component redesign and refactor" part 2 (#svnuserfail)
* show new comments component where required
* comments in correct order
* displaying ok in 1024x768
25907: Clean up redundant javadoc
25909: Wrapped setup and tearDown work in retries
25910: More ALF-7120: TR03: Test and integrate sample site into bootstrap process
- Pulled everything into first-level patch
- Removed build-time dependencies
- Fixed authentication wrapping
- Fixed I18N messages for patch
- Note: The patch ID has changed, but this will not cause problems on re-application
25912: Fixed test fallout from rev 25910 (ALF-7120: TR03: Test and integrate sample site into bootstrap process)
25926: Even more ALF-7120: TR03: Test and integrate sample site into bootstrap process
- Removed exclusions from build script for XML file no longer present
- Fixed an re-enabled JavaScript test in SiteServiceImplTest that was disabled earlier
25928: - Added form config for ActivitiesFeed MBean ready for addition to admin console
- Made all boolean fields use a checkbox
- Re-ordered Fileservers fields to tidy up form and fixed labels
25937: Build fixes, updated counts for groups as there are now more groups in a default repo due to sample site being created.
25940: Added Activities feed admin console component
Fixed label reference in IMAP admin console component
25955: Merged V3.4 to V3.4-TEAM
25946: ALF-7191: Generate duplicate _en resource bundles, using location of _fr bundles as a guide for ALL bundles under alfresco and share WEB-INF/classes
25947: ALF-7191: Reverse accidentally committed changes to WebDAV in 25946!
25954: ALF-7191 - Generate _en bundles for all message bundles for Explorer and Share - using known location of message bundles
25959: Extra logging around ALF-7336: License file to be loadable from configurable location
25962: Updated example JavaScript patch to include an example that starts a pooled review and approve workflow for all the members of the site the document being acted upon belongs to. The script has no effect if the document lives outside a site.
25965: Fixes and tweaks from Alfresco Team UI review meeting
25973: Fixed issue where some form field labels were not returned, was caused by a bean in the enterprise forms context file having a duplicated name.
Also re-enabled the forms tests I disabled as these should now be fixed too.
25977: More TR28: Prevent the IMAP 'Email Actions' folder from being created during bootstrap. The folder structure contains rules that point to the scripts we also no longer bootstrap. This folder is used for optional IMAP functionality which can be enabled by manually importing the ACPs if required.
25982: Merged V3.4 to V3.4-TEAM
25890: Fix for ALF-5796 - It's impossible to add tag in Japanese language (IE specific)
25894: Fixed Legal and License url in About dialog
25896: ALF-6476 -translation on Transfer Target configuration
25899: First cut of French transfer properties. Mostly English! but has 3 lines of French.
25900: Fix for ALF-6916: More Deployment Reports action causes an error
25916: Updated support URL in readme
25925: Fix for ALF-6885: alfresco-enterprise-3.4.0.zip package has 2 issues with apply_amps.sh
25936: ALF-6469 - transfer folders internationalized
25949: Fixes: ALF-6521 and ALF-6493 (Site discussion's handling of tags with special characters in them)
25950: Fixes: ALF-6489 - encodes the content's name to make it safe for a URL.
25951: Fixes: ALF-6487 Adjusts styling for rename panel
25956: Allow a bit of leeway with audit timing during delete tests
25957: Fixed ALF-7341: Upload performance degradation when uploading contents to folders with content rules applied.
- Action executions were being recorded by the ActionTrackingService for all actions
- Post-commit updates of the action node was reducing performance
- Added 'trackStatus' to ActionExecuter, ActionDefinition and Action
- Default 'trackStatus' is false; exceptions: 'replicationActionExecutor' and 'commit-transfer'
- Adjusted tests accordingly
- General cleanup around modifications
25964: ALF-5625 - When viewing properties in version history hitting close results in loop
25970: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/V3.4:
25967: Fix ALF-7440: WQS: commons-pool library has been upgraded, but WQS build properties have not been changed accordingly
25974: Reverted rev 25964 - as fix is scheduled for 3.4.2
25979: Disabling intermittent failing unit test. ALF-7443 logged.
25989: ALF-7457: Update to Team UI following 01/03/2011 review
25990: Fix initial load of my tasks dashlet. Dashlet pagination now hidden if dashlet empty.
25991: Agenda View: fixes minor bugs & attempts to slightly improve usability of Event Info box.
25993: Fix for ALF-7444: RTEAM 41: ActivitiesFeedNotifier fails to send emails (when built using exploded target)
25997: License management debug logging
25998: Temporary logging for license and heartbeat
26008: Merged BRANCHES/V3.4/ to BRANCHES/V3.4-TEAM:
25891: Fixes: ALF-7363 (updated JA translation)
25901: Fixes: ALF-6847 (Italian Translation)
25902: Fixes: ALF-6861 (incorrectly encoded German character)
25904: Fixes: ALF-6755 (translation quoting error)
25911: Fixes: ALF-6478 - French translation correction
25915: Updates TinyMCE translation as requested in ALF-6486.
25917: Fixes: ALF-6482, wrong word order in FR has been corrected.
25913: Fixes: ALF-6334 and ALF-6477 (Profile Edit style issues - makes mark up consistent, clears floats to allow for foreign languages being a tad more verbose than English and adjusts padding to help input boxes line up.
25919: Fixes: ALF-6655 updated to allow enough space for verbose languages (e.g. FR, ES)
25941: Merged BRANCHES/DEV/dwebster/ to BRANCHES/V3.4:
25939: Latest JA update from Translators, received: 2011-02-28
25943: Merged BRANCHES/DEV/dwebster/ to BRANCHES/V3.4:
25942: Language updates for property string changes and additions between 3.4.0 and 3.4.1
26009: Fixes double byte comma issue in JA.
26010: License loading: Further use of the license change callback
- Added notification for license failures
- Heartbeat uses callbacks
- ALF-6884, ALF-6905, ALF-6888
26015: Updated sample site, now contains images that can be distributed.
26016: Temporarily disable failing test: runs locally
26018: Final version of English HTML email templates.
26025: Debug logging to test to trace during builds.
26029: Team unit test fixes and analysis
- Reintroduced UserUsageTrackingComponentTest with debug logging to aid trackability
- Fixed at least one LicenseComponentTest (Trial license generation for forcing read-only mode)
- Added further logging of failed licenses to aid tracability on build box
- Removed temporary debug logging (build box debug logging working fine)
26031: Fixed embedded license loading and logging
26038: Updated Contents.acp of sample site, fixes the broken image link in the wiki's main page
26041: Merged V3.4 to V3.4-TEAM
26024: ALF-7466 - Links do not appear correctly in the management Console (RM)
26033: Correct database cleaning behaviour of continuous build - dir.test.data was never set. dir.root was never getting cleaned.
- dir.test.data replaced with dir.root
26036: ALF-6403: Merged V3.4 to V3.4 (lost revision)
25627: Fixes ALF-7222: Updated linux installer window height (with taller image to hide additional background)
26039: Fix intermittent failures in InviteServiceTest.tearDown()
26040: Fix intermittent failures in InviteServiceTest.setUp()
26046: Test cleanup of license restrictions
26047: Prevent real embedded license from being picked up during unit tests of embedded license
26053: Added in loop to wait for asynchronous post-failure auditing (ALF-3055)
26054: Separation of embedded license location for HeartbeatTest
26055: Merged V3.4 to V3.4-TEAM
26014: ALF-7087 - Cannot override webscript files in case of using jboss 5.1GA
26043: Sync up run-junit-test with junit macros so that it can be used to run unit tests in an enterprise environment (e.g. DB2 / Oracle)
26044: Possibly fix intermittent TransferServiceImplTest failures by using org.alfresco.repo.transaction.RetryingTransactionInterceptor
26052: Do not wait indefinitely for a heartbeat in HeartBeatTest. A broken heartbeat would cause the build to hang forever!
26062: ALF-7492 - MT support for new Team/Enterprise license info retrieval in web-tier.
26064: Fixed ALF-7419: RTEAM 40: Duplicate warning and error messages when user limit reached
26066: Fixed ALF-7489: Team - default outbound email settings need removing
- Now: mail.host=smtp.example.com
- Added this to build env. on bamboo and bamboo2: mail.host=smtp.alfresco.com
26069: Removed unused remote-api bootstrap files
26070: Use PropertyCheck to check for valid property values
26071: Extra debugging during 'split person' processing
26072: ALF-7333: TR24: IMAP, CIFS, WebDAV & FTP should not mount company & user home by default
- WebDAV obeys 'protocols.rootPath'
- Use dedicated bean to ingest properties so that Spring takes care of the placeholders
- Servlet gets the bean instead of using web.xml config values
- Added global property 'protocols.storeName' and injected it into protocol configurations
26073: Follow-up on rev 26069: Removed unused remote-api bootstrap files
26074: ALF-7468: Update to Team UI following 03/03/2011 review
ALF-7474: Check supported mimetypes for new icon support
26075: Latest dashlet help balloon and empty content text. Missing file from r26074. Consolidated Site and Repository DocLib renderers.
26076: Fix to base style for Content I'm Editing dashlet
26078: Fixed the "RM part" of ALF-7013 "Fix up refactored Document Details page and components for RM and WCMQS modules"
26079: Merged V3.4-BUG-FIX to V3.4-TEAM
26057: Fix for ALF-6691 - Incorrect behavior of RSS feed for Wiki. Resolves a number of niggly auth related issues with RSS feeds and auth.
26060: Improvements to error 500 handling page for Share. Complete exception output as HTML comment for administrators and developers. Web-tier server errors now output to the console again also.
26080: ALF-7358 - RTEAM 38: User count is not decremented when users are removed
- Added listening during modification of user (enable/disable)
- Use common warning and error logging: the same logging that is displayed to admin
- Also fixed erroneous logging of person splitting when a user was changed (it was not actually doing anything)
26083: JA file moved to reflect changes made while translation was being done.
26085: Fixed ALF-7529 "No doclib action on details" - caused by double encoding of vtiServer property
26086: ALF-6835 - Report license errors to all users and warnings+errors to admin on first login.
26087: Final implementation of ALF-7230.
- Changed ImapServiceImpl to look for localised siblings of the Imap Email templates. Using the normal FileFolderService method, email templates for IMAP clients will be selected based on server locale.
- Added new email templates for locales: de, es, fr, it.
- Changed existing default locale to use ACP for consistency.
26090: Updated sample site, now includes a video file to highlight new video previewing capabilities
26091: Fixed ALF-7013 "Fix up refactored Document Details page and components for RM and WCMQS modules" part 2 - WCMQS
26092: Addition of patch for non-default locale templates for Imap Clients. (ALF-7230)
Also stepped the db version number.
26098: Minor updates to dashlet help text.
26103: Fixed test after default config for email settings were changed.
26105: ALF-7533: Drag and Drop no longer works into FF3.6 browser
ALF-7532: Content Rule on RM site (other than Folder) creates 'GUID' folder in Share (fixed as part of general RM fixes)
Also: RM and WCM QuickStart Document Library extensions patched to latest code. WCM QuickStart toolbar extension removed. Drag and Drop refactored to work in Repository Browser and WCM QuickStart; switched off for RM. English property files created when using Slingshot exploded target. Header conditions updated to use correct Community edition string.
26106: Remove debug output.
26108: Fix for ALF-7331. Thumbnails in Share do not change from initial generic filetype icon...
The fix is to have StreamContent.java use the actual resource's modification timestamp for the Last-Modified header.
It was using the mod-time of a newly created file, which held a copy of the classpath resource.
This led to a race condition between putting a timestamp on the placeholder and putting a timestamp on the cm:thumbnail node.
26113: Fix slingshot-exploded target - missed commit from yesterday.
26114: Merged V3.4 to V3.4-TEAM
26077: Upped LOGFILSIZ to avoid failures in unit tests with large transactions on DB2
26084: Avoid intermittent test failures in AbstractTestFormRestApi by using retrying transactions
26096: Correction to DB2 drop / create commands
26097: Fixes: ALF-7102, typo in property string.
26102: Attempt to avoid intermittent failures in TaggingServiceImplTest by upping wait time
26109: Another go at executing the db2 creation statements synchronously through db2cmd
26111: ALF-6764 - Copyright year on Share login page out of date
26118: Made the JMXFormProcessorTest more resilient to changes in the email configuration.
26122: Fix customize site page following refactoring in r26078. Added Data List page icon.
26126: Merged V3.4-BUG-FIX to V3.4-TEAM
26099: Resolve ALF-7539: Tomcat sessions are created unnecessarily when invoking CMIS web scripts from Web Quick Start
26129: ALF-6929: RTEAM 21: activities feed notifier - add per user on/off flag
26149: Removed old System.out
26150: Fixed ALF-3856: Version History lost when Versionable Content renamed via CIFS
- Added fileservers property: filesystem.renameShufflePattern=(.*\.tmp)|(.*\.wbk)|(.*\.bak)|(\\~.*)
- Any rename that does not match the pattern on either the source or target names will not be shuffled
- Requires retesting of use cases involving CIFS and MS Word.
26151: ALF-6626 TR15: Email notification preferences
Cleanup to related components
26161: Fix full installer.
26162: Updated calendar help with latest icons and styling to match.
26168: Use new install builder 7.0.3
26169: Localized installer.
26173: Tweak to display of warnings/errors after login - reduced impact on server
26200: Locate Postgres data within alf_data directory
26209: Locate Postgres data within alf_data directory for Team
26210: Set license path to include install dir, and set protocol root to Sites
26215: The ContentTransformerRegistry and the ContentService used to only expose the 'best' transformer for a given (srcMime, targetMime, options). This check-in adds access to the full list of active transformers for any (srcMime, targetMime, options) to those two classes.
As part of a subsequent fix for ALF-5084, the ThumbnailService will use this list to improve create-thumbnail retry behaviour for problem files.
26227: Merged V3.4-BUG-FIX to V3.4-TEAM
26226: Merged DEV/SWIFT to V3.4-BUG-FIX
26225: 'renameShuffle' detection pattern needed extending and logic was slightly incorrect
- Fallout from fix for ALF-3856 detected by new unit tests
26235: Merged V3.4 to V3.4-TEAM
26233: Fixes ALF-6019: Ensure PostGres services deleted after installation cancel
26264: ALF-7653 - sys-admin panel no longer editable
26265: Merged V3.4-BUG-FIX to TEAM
26263: Merged DEV/SWIFT to V3.4-BUG-FIX
26262: Fixed regex patterns to cater for .properties file escapes (ALF-3856)
26266: ALF-7651 - WebM and OGG Video have 'unknown' mimetype in Team
26267: ALF-7578 - When importing from an ACP a node with the versioned aspect on it, have an initial version history created starting at the current version label.
26268: ALF-7687 - Ability to use wild character in People search - Should add configuration to allow zero characters for all search in Team config.
26272: ALF-7578 - Add unit test for versionable ACP import, and fix the default aspect includes now that we handle versionable
26287: Fixes ALF-7439: Prevent check on alfrescowcm component
26290: Fixes ALF-7439: Ensure that virtual server shortcuts don't get created for Team
26294: Fixed @since tags and some minor coding standards fixes
26316: Fix for ALF-5084, ALF-5644 and general thumbnail improvements in the area of failing thumbnails.
This check in adds extra functionality to the create-thumbnail action in order to improve how Alfresco handles failing thumbnails.
The requirements agreed between Services & Prod Mgt were
- When thumbnails fail we should limit how often they are retried. So the system should remember when a thumbnail has failed for a node.
- The retries will be initiated in the same way they are now: by users navigating to a page that asks for the thumbnail (lazy creation), primarily doclib.
- Retries will occur at a throttled rate (all the below parameters to be configurable by sys admin, but not yet by JMX).
- Initially, retries will be limited to a maximum rate e.g. 1 per minute.
- These retries will be allowed up to a maximum count e.g. 2 failed attempts.
- After that count is reached, the content will be considered "difficult" and thumbnail creation should be retried at a much reduced maximum frequency e.g. once a week
- Retries of difficult content shall be enabled by default, but can be disabled.
This check-in adds a new aspect and a type to the content model. These hold the thumbnail failure information.
The create-thumbnail action now has a compensating action which is run when it fails.
AddFailedThumbnailActionExecuter decorates the content node with failure information.
create-thumbnail now has an action-condition, which means that it will only run if a node is "eligible" for a thumbnail creation attempt.
Eligibility is controlled by some new properties and is configurable. Default behaviour is as described above.
There should be no change in behaviour for most content nodes in Alfresco.
However, for those documents which fail to produce doclib or webpreview thumbnails - and most especially those which consume 100% cpu for some time before failing - we expect to see the same behaviour initially on upload (cpu grind as Alfresco or a 3rd party library attempts to produce a thumbnail), but that as time passes, Alfresco should prevent thumbnail creation that will likely not succeed. This should save cpu on the repo server.
And tests. Of course.
26323: Upgraded login warning to WARN_ALL when user limit reached
- This now matches the specification document
- ALF-6832:TR25: License restriction reporting
26326: Merged V3.4 to V3.4-TEAM
26142: Merged PATCHES/V3.4.0 to V3.4
25999: ALF-7377: Validate and reject partial WebDAV requests sometimes produced by NetDrive
26143: Merged PATCHES/V3.4.0 to V3.4
26005: Merged V3.4-BUG-FIX to PATCHES/V3.4.0
26002: ALF-7282 Updated NodeListConverter so that it now implements the method revert(Object, ProcessDefinition)
26158: Merged DEV/TEMPORARY to V3.4
26154: ALF-7571: Create Web Project wizard - Step 3
Superfluous “cellpadding” elements were removed. Missing space was added.
26164: ALF-6885: Changed svn:eol-style from native to LF for all .sh scripts
26178: Merged DEV/TEMPORARY to V3.4
26172: ALF-7601: 3.4.1 SDK WebServiceSamples multiple problems
Configuration properties for WebServiceSamples was moved to correct place.
Dependency to SDK AlfrescoEmbedded was added to classpath. It is required for FileCopyUtils from Spring which is used in WebServiceSamples.
26190: Reversed 26165 / 26161 - breaks installer building
26192: Convert TaggingServiceImplTest to use retrying transactions!
26194: ALF-7045: AVM upgrade - re-implement AVM "rename duplicates" patch as a DB upgrade script
26195: Update installer overlay files
26197: Final installer updates - built and tested on OSX
26199: Allow relocatable data for postgres - part2
26204: Attempt to avoid intermittent unit test failures in RecordsManagementAuditServiceImplTest by adding some Thread.sleep() calls to allow for asynchronous audit behaviour
26207: Set site notification to false on install (ALF-6181)
26212: Merged DEV to V3.4
26203: ALF-7605 PostgreSQL: Upgrade from 2.1.7 to 3.4.1 is failing - constraint "alf_access_control_entry_acl_id_key" does not exist
1. The statements which are drop constraints, marked as optional
2. The alter statements with new constraint names were added
26256: Fixes ALF-7679: Remove webscript-framework-config-custom.xml file
26270: License updates from Ashutosh
26274: Fix intermittent unit test failure with retrying transaction
26275: Possible fix to intermittent test failure.
26295: Reduce scope of retrying transaction, in a hope of fixing TaggingServiceImplTest.testOnStartupJob()
26303: And the prize for the largest number of retrying transactions in a single unit test goes to...
26307: Fixes: ALF-7704: Japanese language option not appearing in dropdown box on log in page.
26314: Another defensive sleep() in RecordsManagementAuditServiceImplTest
26325: Moved defensive sleep() in RecordsManagementAuditServiceImplTest
26336: Fixes ALF-7713: Prevent folder/documents from being draggable in DocLib
26348: Fix for ALF-7751 - encode all params on new Team dynamic welcome dashlet
26351: Removed svn:mergeinfo
26353: ALF-7745 - Add pop-up balloon validation helper to create site dialog.
URL Name (shortName) is now also auto-generated from the site name (siteTitle) by removing characters other than 0-9, a-z, A-Z and "-", replacing spaces with "-" and converting to lower case. Auto-generation is stopped if the user edits the URL Name field themselves and restarted if they empty the field.
Update to Preference Service to allow "-" character in preference keys.
26355: ALF-7743 - Increase delay on "More actions panel" in document library
26361: ALF-7758 - Site Dashboard: Welcome widget isn't removed immediately
26364: Updated UI Text strings following review by Linton.
26366: Fix for ALF-7757 - Calendar agend view encoding
26368: Fix for ALF-7739 - Click activity link for a file after DnD upload results in an error
26369: Merged V3.4-BUG-FIX to V3.4-TEAM
26340: Fixed ALF-6377 "Incorrect behavior of Overdue filter in My Tasks Dashlet"
26374: Further UI text updates from Linton
26377: Updates to ACPs as part of ALF-7382 Translate/Localise HTML email templates.
This check in adds localisations in de, es, fr, it, ja for the following email templates:
activities-email
imap_message_text_html
imap_message_text_plain
invite-email
new-user-email
notify
26381: Set site invites on by default for Team.
26384: ALF-7733 - Data list's type isn't included for deleted activities
26385: ALF-3709 - User Status on Profile
26389: Merged V3.4-BUG-FIX to V3.4-TEAM
26372: Fix for ALF-7791 - no longer spews masses of exceptions when doc details page for a missing node is displayed.
Node Metadata retrieval service now returns valid JSON in all cases.
26390: Fixed ALF-7689 "Team: Dashlet names don't match dashlet titles"
26391: ALF-7718 - Handle excel files without a freezepane, eg those created by hand rather than using the friendly template
26394: Merged V3.4-BUG-FIX to TEAM
26392: Removed code which sets the cm:title property to the filename in the upload webscript. This was causing an unnecessary auditable update.
26393: Line endings
26403: Fix for ALF-7832 - Licence warning for all users on WARN_ALL
26409: ALF-7763 - Updates to dashlets in Team following usability studies, including: presentation of "no data" made consistent. Page-level inline JavaScript wrapped in module mark-up.
26410: Fix license location for Win installs
26425: Fixed ALF-7726: 'Repository Descriptor (Originally Installed)' form doesn't contain Name and Edition information.
Also updated the 'Heartbeat Disabled' field in the License form to use a checkbox control.
26426: ALF-7742 - Remove title field on simple edit metadata pop-ups
26427: ALF-7665 - Team: Duplicate Help links in toolbar
26434: ALF-7875 - CLONE -Unable to browse into folders in Share Site
26435: Moved of Ent/Team logos to overlays, empty logos in place
26437: Merged HEAD to V3.4-TEAM
24723: ALF-5799: Type-ahead functionality for tags
26438: Merged BRANCHES/DEV/dwebster to BRANCHES/V3.4-TEAM:
26431: Latest Spanish language Pack updates
26429: Latest Italian language Pack updates
26428: Latest French language Pack updates
26422: Latest German language Pack updates
26444: Merged V3.4-BUG-FIX to V3.4-TEAM
26186: Improvements to tree node handling and Bubbling library following investigation for ALF-6960 and ALF-7296
26189: (Partial merge due to refactoring) ALF-7077 - Unable to set a Repository library root node by XPATH
Merged HEAD to V3.4-BUG-FIX
24021: Share Repository Browser support for xpath starting location. See comments in "RepositoryLibrary" section of share-config-custom.xml.sample.
26183: ALF-6960 - Actions "Copy to..." and "Move to..." Repository don't display the Path. ALF-7296 - Copy or Move content from a site document library to the repository do not work.
26191: Prevent MooTools JavaScript library being compressed on every build. Added minimized file to source tree. Added target "minimize-mootools-javascript" which inserts a reminder comment to the top of the minimized file.
Also reverted inadvertant line-endings swap in build.xml from r25479
26282: ALF-6728 - Unable to open office documents via Share Site > Document Library > All Documents > Edit Online
Reworked calculations around the "location" field so that the attributes within are returned more consistently.
26297: ALF-3113 - Data Lists: Delete/duplicate multiple items should affect only selected items on current page
26298: ALF-7609 - Items numbering in document library in Share appears quite ambiguous in case of documents with working copies
26312: ALF-4220 - Alfresco Share - Tag component - Unable to view more than 100 tags
Object finder-based pickers now look for "maxSearchResults" in the control params (rather than the args property bag)
26445: Merged V3.4 to V3.4-TEAM:
26443: Installer build updates
26447: Merged V3.4-BUG-FIX to V3.4-TEAM
25975: ALF-5625 - When viewing properties in version history hitting close results in loop
26174: *Record only* Fix spring-surf library versions after merge in rev 26144
26175: Fix for ALF-7201 - Unable to create group with other name if group identifier is already exists
26187: Fix for ALF-7297 - Share Advanced Search does not work if the property name include a minus (or any symbol not supported by SQL92 identifier standard)
26240: Fix for ALF-7462 - Share - User profile / Non-ASCII characters display (double encoding of user description field)
26242: ALF-3767 - Creating account with 0 quota in Share gives unlimited quota
26279: ALF-7682 - Fix to correctly take the 'external-auth' config setting into account when testing for login auth against the default alfresco endpoint.
26280: Fix for ALF-7391 - In the search properties in share, repository is spelt wrong.
26401: Fix for ALF-7428 - Share: User cannot add comment to content when the 'admin' user is not in administrator group
26405: Fixed ALF-7224 "Share - Scrollbar issue on dashboard customization page"
26451: Merged V3.4-BUG-FIX to V3.4-TEAM
26399: Fix for ALF-5863 - DOCLIB: large number of tags slows doclib rendering to unusable.
Number of tags to display in the Tags filters is now configuration and defaults to 100 items. Can be configured with value of -1 to show all tags.
26456: Merged BRANCHES/DEV/dwebster/ to BRANCHES/V3.4-TEAM:
26450: Latest Japanese language Pack updates
26458: Merged BRANCHES/V3.4/ to BRANCHES/V3.4-TEAM:
26417: Fixes: ALF-7414, confused and hardcoded date-formatting & date formatting translations fixed.
26414: Fixes: ALF-7697 - Rewording the URL help text on the create site dialogue
26413: Fixes: ALF-7765 - ensures naming consistency
26461: Merged V3.4-BUG-FIX to V3.4-TEAM
26243: Fixes ALF-7301: IE6 CSS updates to prevent layout corruption on datagrid
26404: Fixes ALF-7348: Copy to/Move to width changes for IE6 & IE7
26453: Fix unreported issue with the appearance of tags in the object finder being stacked vertically rather than horizontally for IE6 and IE7.
26464: Merged V3.4-BUG-FIX to V3.4-TEAM
26463: Follow-up fix to r26453 for full-page edit mode
26465: ALF-7869 - Layout is broken if many tags are added to the item (Document Library browse view)
26466: Merged BRANCHES/DEV/dwebster/ to BRANCHES/V3.4-TEAM:
26459: Fixes incorrectly translated stirngs.
26467: Merged V3.4-BUG-FIX to V3.4-TEAM
26334: Fixed ALF-6289 "Contributor is absent in Permissions section at the details page" part 2 - now also on folder details page
26468: Fixed bug when content size was 0, now the "Preparing previewer..." message is replaced with a message saying "This document has no content"
26469: Fixed ALF-7744: Ensure that new options.limit gets set when updating RSS feed results
26472: Activity list: css class for each activity type into config
26473: Remove references to non-existent client-side "document-details.js" file
26475: Calendar UI Bug fixes & improvements from usability feedback (inc. ALF-7592, ALF-7588, ALF-7590, ALF-7594, ALF-7589, ALF-7595, ALF-6959)
26477: IE6/IE7 css fixes: Fix footer layout and prevent unnecessary horizontal scrollbar
26482: Merged BRANCHES/DEV/dwebster/ to BRANCHES/V3.4-TEAM:
26480: Latest Update from Translators via Gloria.
26485: Fix for ALF-7728. Incorrect information at the Trash page.
The 'archived by' as returned from the REST API was not the user who archived the node, but was instead the
original owner of that node. This has now been corrected.
26494: Small fix from translator
26496: Installer NLS updates
26498: Merged V3.4-BUG-FIX to V3.4-TEAM
26486: Fix for ALF-7602, ALF-7734 - Incorrect behavior of groups - groups in non-default zone displayed in Share UI
26501: Added translations for "Contributor" role.
26506: Merge V3.4 to V3.4-TEAM:
Fixes ALF-7735: Update to postgres.xml to make use of vcruntime on 64-bit windows (fix dependent upon additional update to ALF-BINARIES)
26513: Merged V3.4-BUG-FIX to V3.4-TEAM
26512: Fix for ALF-7921 - Script error occurs when is added 'Image preview' dashlet.
26516: Fixed ALF-7791 "Clicking the activity link for a file after deleting that file results in an error"
26517: Removed unused component files since document details page refactor
26532: ALF-7946 - It's impossble to destinate More+ administrator menu.
combinePaths() function reworked to maintain trailing "/" if the last argument ends with one.
26536: ALF-7948 - IE Specific - It's impossible to download document via Download button at the details page
26541: Fixed ALF-7868: Import site doesn't work (QA were trying a scenario that we aren't supporting, removing the old sample context file to avoid problem/confusion)
26545: Fixed ALF-7001 "Customize site drag and drop - page item is added to end of list if quickly dragged and dropped"
26550: Fixes: ALF-7935, typo in message string.
26556: UI improvements and Ajax-ified performance improvements to Image Summary dashlet
26561: Fix for ALF-7888. Sites are not recovered.
The fix applied is to mark site nodes with the sys:temporary aspect within the SiteService in order to have them be fully deleted immediately and not go into the trashcan.
26562: ALF-7925 - Incorrect behaviour of Categories cloud at the Document Library page
26563: ALF-7912 - Incorrect behavior of items marked as favorite - IE specific
26570: Update build to correct installer file names.
26572: Team installer build tweak (added back project filename removed during merge)
26573: Merged V3.4-BUG-FIX to V3.4-TEAM
26564: Fix for ALF-7965 - Content page of user profile not updating properly (modified docs always shown in the recently added list)
Improvements to show filetype icon - FreeMarker macro to mirror basic functionality of Alfresco.util.getFileIcon
26574: ALF-7962 - Team: Create Site dialog fields aren't cleared on Cancel
26575: ALF-7970 - Links 'Show Earlier Events/Show Later Events' don't work in IE browser
26578: Merged V3.4 to V3.4-TEAM:
26542: Fixes ALF-7954: Ensure that installer copies SWFTools to correct location
26586: Added script model object "msg" helper to retrieve I18N messages for template level JS controller (mirroring the support in WebScript component JS model)
26595: ALF-7982 - Filetype icon isn't displayed for topic's reply in activities
26597: Fixes ALF-7845: Provide tooltip assistance when DocLib upload dialog launched from site welcome dashlet (when DnD is available)
26605: Fixed ALF-7681 "Renames of Document Library not reflected in page title."
26617: removed svn:mergeinfo
26622: JMX Admin pages UX fixes:
- The Save & Cancel buttons on the jmx admin console pages have been configured not to be displayed.
- A a "Cancel" link is present instead.
- The "Operations" header has been removed
- The "save operation" button now has an "Update" label instead of "Save"
26625: Reduced distribution artifacts to minimum (now no E3.5 planned)
26653: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/V3.4-TEAM:
26619: ALF-6244 - Creating the initial version of a node shouldn't update the Auditable properties
26623: Add new Version Service method "ensureVersioningEnabled".
26624: ALF-6121 + ALF-6244 - When activating lazy versioning for share, use a ScriptNode call to the Version Service
26654: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/V3.4-TEAM:
26631: Improvement related to ALF-6650. Secured PDFs in Acrobat 9 fail to rendition.
26657: Merged V3.4-BUG-FIX to V3.4-TEAM
26655: Add parameter comments around ensureVersioningEnabled() function call.
26660: Fixes ALF-7955: Update error message when dropping zero byte size files or folders into doc lib
26662: Merged V3.4-BUG-FIX to V3.4-TEAM
26661: ALF-8053 - Document Library is attempting to create thumbnails for types that are not subtypes of cm:content. Also prevent thumbnail webscripts from attempting to generate thumbnails for in the same cases.
26665: Fixed ALF-8042 "Renamed page component reverts to default name when moved (Customize Site page)"
26673: Merged V3.4-BUG-FIX to V3.4-TEAM
26672: Consolidate multiple occurrences of "#yui-history-iframe" style into base.css
Also fixed markup issue in console-tools that was confusing MSIE browsers.
26676: Additional fix for ALF-7687 "Ability to use wild character in People search - Should add configuration to allow zero characters for all search in Team config."
- start workflow component now picks up global min & max search length config
26677: ALF-8019 - Delete folder window has incorect name
26678: Merged V3.4-BUG-FIX to TEAM
26383: Fixed ALF-7692: Non-admin users can move content into Company Home
26430: More ALF-7692: Non-admin users can move content into Company Home
- Handles duplicate ALF-7923
26679: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/V3.4-TEAM:
26439: Probable fix for ALF-7482. Custom ImageMagick parameters not being accepted on Linux Alfresco server.
26680: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/V3.4-TEAM:
26474: Fix for ALF-6730 Preview and thumbnails are not update with new revision of the document is uploaded.
Added a compensating action to ensure that renditions are deleted when re-renditions fail on new content.
26682: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/V3.4-TEAM:
26675: Fix for ALF-7334 Could not upload new Version all Dokuments.
Issue was resolved by adding "RunAs System" boilerplate to the few places that load (and in the case of the WQS, delete) rendition definitions.
We purposely did not add this boilerplate within the RenditionServiceImpl.loadRenditionDefiition() method as we want to retain effective permission controls for normal client code.
Added some javadoc to highlight the permissions issues involved.
I also took the opportunity to add a convenience method to the RenditionService, namely render(NodeRef, QName) which will allow client code to execute built-in rendition definitions (e.g. thumbnails) without worrying about permissions on Data Dictionary. That method wraps the equivalent render(NodeRef, RenditionDefinition) in a RunAs System.
26685: Fixed ALF-7880 "Download version form version history shows incorrect document name"
26688: ALF-7919 - Use 'Properties' instead of 'Metadata' in actions, titles etc.
26690: Partial fox for ALF-8014. thumbnail and file type aren't generated for *.eps files
A placeholder 'doclib' icon is now available for .eps files.
26697: ALF-7004: TR28: Create HTML email templates (Implemented Linton's richer HTML email template design)
Also removed the timestamp from the email subject for the Activities email as the timestamp is now within the body of the email.
NOTE: You need to start with a clean database in order to see the new templates.
26698: Build fix since label change of Start operation button in admin console (JMX) forms.
26699: Fixed ALF-7886 "Click here to Download gives incorrect document name"
26700: Fixed ALF-7801 "Incorrect hint for Upload new version action in Versions pane"
26702: Fixed ALF-7857 "Team: Inconsistency between DocLib action and tooltip text"
26703: Fixes ALF-7762: Add tooltips to dashlet toolbar actions
26704: Fix for ALF-7785 - Agenda View doesn't always update list after Edit/Delete of an item
26708: Merged V3.4-BUG-FIX to TEAM
26664: Fix build (DOD5015 security context and test refactor)
26709: Slight reworking (and rewording) of the tooltip on the upload dialogs when drag and drop is available (the "#upload" use case)
26710: Move style fixes into IE specific CSS files to avoid breaking layout on other browsers
26712: Merged V3.4-BUG-FIX to V3.4-TEAM
26711: ALF-3833 - Share - Phrase tags
26714: ALF-8081 - W3C: a highlighting of drop-down menu (Sites, People) in toolbar is invisible in Safari.
26715: Tweak to imagesummary dashlet node cloning performance
26716: ALF-8082 - W3C: it's impossible to select a lot of links in Safari
ALF-8083 - W3C: it's impossible to select Site Pages in Safari
26718: Fixes for ALF-7874, ALF-8012 - Mimetype map additions, filetype icons.
- also replaced worlds-largest if-else freemarker statement with inline map for Forms mimetype lookup
26719: Further fix for ALF-8014. Thumbnail and filetype not generated for *.eps files.
I've added a -file-48.png for the .eps mimetype.
I copied it from one of the other image -48.png files as they're all generic 'img' icons anyway.
26721: Fix for ALF-7963 Team: Can edit another user's email notification settings
26722: Collapsed/expanded state of Properties panel wasn't being remembered on Details page. Removed "collapsed" parameter for Alfresco.util.createTwister which won't work with our current implementation. Pre-empted "alfresco-twister" class for slow-loading components.
26723: Changed component initialisation event from onContentReady to onAvailable which should improve appearance/decoration times slightly.
26724: ALF-8089 - W3C: a highlighting of "Show Earlier Events" and "Show Later Events" links in toolbar is invisible in Safari
26731: ALF-8095 - Error shown after clicking the accept or reject link in a site invitation email
26733: Merged V3.4 to V3.4-TEAM
26530: Fixes ALF-7949: Remove service script on uninstall
26610: Fix for: ALF-8007: Lucene index not coherent or not up to date or we can not rely on it to check that a working copy exist.
26734: Merged V3.4 to V3.4-TEAM (RECORD ONLY)
25971: ALF-7441: Help URLs pointing to new doc system (1 of 2)
25972: ALF-7441: Help URLs pointing to new doc system (2 of 2)
25980: Merged V3.4-BUG-FIX to V3.4
25978: ALF-7394 - Alfresco Network dashlet, now Alfresco Support information
26056: Merged V3.4-TEAM to V3.4
26053: Added in loop to wait for asynchronous post-failure auditing (ALF-3055)
26100: Merged V3.4-TEAM to V3.4
25985: Another cycle of fixing installer from Win builds. Still waiting for official fix from Bitrock.
26067: Fixes for installer builds on Windows
26127: Merged V3.4-TEAM to V3.4
26120: Fix postgres.bki on Win builds
26165: Merged V3.4-TEAM to V3.4
26161: Fix full installer.
26737: Google Docs: Added better handling of unsupported mimetypes
* Meaningful exception raised when mimetype unsupported by GDoc (rather then non-specific error from google)
* Message not reflected in UI, but log contains details of failure
26738: Clarified browser relevance for "in-memory-limit" config parameter following ALF-8093 being raised.
26740: Quick build fix following Google Docs updates in r26737
26741: Build Fix
* Added missed exception class
* backout previous fixes
26746: Fixed ALF-8080 "WebM playback not working for Team and Chrome"
26750: Prettifying the delete url for comments to avoid two ampersands following each other, i.e: "&&". This is NOT a fix for deleting content with "%" in the name.
26753: Fixed ALF-7807 "It's possible to rename component with spaces"
26756: ALF-8102 - Edit Properties, Edit tags, Manage permissions, Start workfow icons are not visible - IE 7 specific
26758: ALF-8106 - "Go Back" button doesn't work on the "User Profile" page
26763: Fixes: ALF-7815 - Added .ics extension and site name to downloaded file.
26779: Merged V3.4 to V3.4-TEAM
26760 : Enterprise unlimited licenses get invalidated turning the system into read-only mode
26782: Fixed ALF-7001 "Customize site drag and drop - page item is added to end of list if quickly dragged and dropped"
26784: Minor height adjustment to "My Documents" dashlet on first use
26786: Correction to merge 26779
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@26795 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -592,7 +592,7 @@ var AlfTagger = new Class(
|
||||
}.bind(this);
|
||||
|
||||
// execute ajax service call to retrieve list of child nodes as JSON response
|
||||
new Ajax(getContextPath() + "/wcs/collaboration/tagActions?a=add&t=" + tagName,
|
||||
new Ajax(getContextPath() + "/wcs/collaboration/tagActions?a=add&t=" + encodeURIComponent(tagName),
|
||||
{
|
||||
method: 'post',
|
||||
headers: {'If-Modified-Since': 'Sat, 1 Jan 2000 00:00:00 GMT'},
|
||||
|
||||
@@ -1006,7 +1006,21 @@ alfresco.xforms.RichTextEditor = alfresco.xforms.Widget.extend({
|
||||
img.setAttribute("src", urlToReplace + href);
|
||||
}
|
||||
});
|
||||
|
||||
//ALF-6807 fix
|
||||
$each(this.widget.getElementsByTagName("a"),
|
||||
function(a, index)
|
||||
{
|
||||
var href = a.getAttribute("href");
|
||||
if (href && href.match("^/"))
|
||||
{
|
||||
var urlToReplace = alfresco.constants.AVM_WEBAPP_PREFIX;
|
||||
if (alfresco.constants.AVM_WEBAPP_CONTEXT == "ROOT")
|
||||
{
|
||||
urlToReplace = alfresco.constants.AVM_WEBAPP_URL;
|
||||
}
|
||||
a.setAttribute("href", urlToReplace + href);
|
||||
}
|
||||
});
|
||||
if (!this.isReadonly())
|
||||
{
|
||||
this.domNode.onmouseover = this._div_mouseoverHandler.bindAsEventListener(this);
|
||||
|
||||
+27
-10
@@ -5,26 +5,30 @@
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each;
|
||||
|
||||
/**#@+
|
||||
* @class This class handles the loading of themes/plugins or other add-ons and their language packs.
|
||||
* @member tinymce.AddOnManager
|
||||
/**
|
||||
* This class handles the loading of themes/plugins or other add-ons and their language packs.
|
||||
*
|
||||
* @class tinymce.AddOnManager
|
||||
*/
|
||||
tinymce.create('tinymce.AddOnManager', {
|
||||
items : [],
|
||||
urls : {},
|
||||
lookup : {},
|
||||
onAdd : new Dispatcher(this),
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
/**
|
||||
* Fires when a item is added.
|
||||
*
|
||||
* @event onAdd
|
||||
*/
|
||||
onAdd : new Dispatcher(this),
|
||||
|
||||
/**
|
||||
* Returns the specified add on by the short name.
|
||||
*
|
||||
* @method get
|
||||
* @param {String} n Add-on to look for.
|
||||
* @return {tinymce.Theme/tinymce.Plugin} Theme or plugin add-on instance or undefined.
|
||||
*/
|
||||
@@ -35,6 +39,7 @@
|
||||
/**
|
||||
* Loads a language pack for the specified add-on.
|
||||
*
|
||||
* @method requireLangPack
|
||||
* @param {String} n Short name of the add-on.
|
||||
*/
|
||||
requireLangPack : function(n) {
|
||||
@@ -53,6 +58,7 @@
|
||||
/**
|
||||
* Adds a instance of the add-on by it's short name.
|
||||
*
|
||||
* @method add
|
||||
* @param {String} id Short name/id for the add-on.
|
||||
* @param {tinymce.Theme/tinymce.Plugin} o Theme or plugin to add.
|
||||
* @return {tinymce.Theme/tinymce.Plugin} The same theme or plugin instance that got passed in.
|
||||
@@ -68,6 +74,7 @@
|
||||
/**
|
||||
* Loads an add-on from a specific url.
|
||||
*
|
||||
* @method load
|
||||
* @param {String} n Short name of the add-on that gets loaded.
|
||||
* @param {String} u URL to the add-on that will get loaded.
|
||||
* @param {function} cb Optional callback to execute ones the add-on is loaded.
|
||||
@@ -85,11 +92,21 @@
|
||||
t.urls[n] = u.substring(0, u.lastIndexOf('/'));
|
||||
tinymce.ScriptLoader.add(u, cb, s);
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
|
||||
// Create plugin and theme managers
|
||||
tinymce.PluginManager = new tinymce.AddOnManager();
|
||||
tinymce.ThemeManager = new tinymce.AddOnManager();
|
||||
}());
|
||||
}(tinymce));
|
||||
|
||||
/**
|
||||
* TinyMCE theme class.
|
||||
*
|
||||
* @class tinymce.Theme
|
||||
*/
|
||||
|
||||
/**
|
||||
* TinyMCE plugin class.
|
||||
*
|
||||
* @class tinymce.Plugin
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* $Id: ControlManager.js 999 2009-02-10 17:42:58Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function(tinymce) {
|
||||
tinymce.CommandManager = function() {
|
||||
var execCommands = {}, queryStateCommands = {}, queryValueCommands = {};
|
||||
|
||||
function add(collection, cmd, func, scope) {
|
||||
if (typeof(cmd) == 'string')
|
||||
cmd = [cmd];
|
||||
|
||||
tinymce.each(cmd, function(cmd) {
|
||||
collection[cmd.toLowerCase()] = {func : func, scope : scope};
|
||||
});
|
||||
};
|
||||
|
||||
tinymce.extend(this, {
|
||||
add : function(cmd, func, scope) {
|
||||
add(execCommands, cmd, func, scope);
|
||||
},
|
||||
|
||||
addQueryStateHandler : function(cmd, func, scope) {
|
||||
add(queryStateCommands, cmd, func, scope);
|
||||
},
|
||||
|
||||
addQueryValueHandler : function(cmd, func, scope) {
|
||||
add(queryValueCommands, cmd, func, scope);
|
||||
},
|
||||
|
||||
execCommand : function(scope, cmd, ui, value, args) {
|
||||
if (cmd = execCommands[cmd.toLowerCase()]) {
|
||||
if (cmd.func.call(scope || cmd.scope, ui, value, args) !== false)
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
queryCommandValue : function() {
|
||||
if (cmd = queryValueCommands[cmd.toLowerCase()])
|
||||
return cmd.func.call(scope || cmd.scope, ui, value, args);
|
||||
},
|
||||
|
||||
queryCommandState : function() {
|
||||
if (cmd = queryStateCommands[cmd.toLowerCase()])
|
||||
return cmd.func.call(scope || cmd.scope, ui, value, args);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
tinymce.GlobalCommands = new tinymce.CommandManager();
|
||||
})(tinymce);
|
||||
+41
-17
@@ -1,17 +1,17 @@
|
||||
/**
|
||||
* $Id: ControlManager.js 920 2008-09-09 14:05:33Z spocke $
|
||||
* $Id: ControlManager.js 1190 2009-08-12 17:59:29Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
// Shorten names
|
||||
var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, extend = tinymce.extend;
|
||||
|
||||
/**#@+
|
||||
* @class This class is responsible for managing UI control instances. It's both a factory and a collection for the controls.
|
||||
* @member tinymce.ControlManager
|
||||
/**
|
||||
* This class is responsible for managing UI control instances. It's both a factory and a collection for the controls.
|
||||
* @class tinymce.ControlManager
|
||||
*/
|
||||
tinymce.create('tinymce.ControlManager', {
|
||||
/**
|
||||
@@ -19,6 +19,7 @@
|
||||
* Consult the Wiki for more details on this class.
|
||||
*
|
||||
* @constructor
|
||||
* @method ControlManager
|
||||
* @param {tinymce.Editor} ed TinyMCE editor instance to add the control to.
|
||||
* @param {Object} s Optional settings object for the control manager.
|
||||
*/
|
||||
@@ -40,13 +41,10 @@
|
||||
});
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns a control by id or undefined it it wasn't found.
|
||||
*
|
||||
* @method get
|
||||
* @param {String} id Control instance name.
|
||||
* @return {tinymce.ui.Control} Control instance or undefined.
|
||||
*/
|
||||
@@ -57,8 +55,9 @@
|
||||
/**
|
||||
* Sets the active state of a control by id.
|
||||
*
|
||||
* @method setActive
|
||||
* @param {String} id Control id to set state on.
|
||||
* @param {bool} s Active state true/false.
|
||||
* @param {Boolean} s Active state true/false.
|
||||
* @return {tinymce.ui.Control} Control instance that got activated or null if it wasn't found.
|
||||
*/
|
||||
setActive : function(id, s) {
|
||||
@@ -73,8 +72,9 @@
|
||||
/**
|
||||
* Sets the dsiabled state of a control by id.
|
||||
*
|
||||
* @method setDisabled
|
||||
* @param {String} id Control id to set state on.
|
||||
* @param {bool} s Active state true/false.
|
||||
* @param {Boolean} s Active state true/false.
|
||||
* @return {tinymce.ui.Control} Control instance that got disabled or null if it wasn't found.
|
||||
*/
|
||||
setDisabled : function(id, s) {
|
||||
@@ -89,6 +89,7 @@
|
||||
/**
|
||||
* Adds a control to the control collection inside the manager.
|
||||
*
|
||||
* @method add
|
||||
* @param {tinymce.ui.Control} Control instance to add to collection.
|
||||
* @return {tinymce.ui.Control} Control instance that got passed in.
|
||||
*/
|
||||
@@ -108,6 +109,7 @@
|
||||
* It first ask all plugins for the specified control if the plugins didn't return a control then the default behavior
|
||||
* will be used.
|
||||
*
|
||||
* @method createControl
|
||||
* @param {String} n Control name to create for example "separator".
|
||||
* @return {tinymce.ui.Control} Control instance that got created and added.
|
||||
*/
|
||||
@@ -138,6 +140,7 @@
|
||||
/**
|
||||
* Creates a drop menu control instance by id.
|
||||
*
|
||||
* @method createDropMenu
|
||||
* @param {String} id Unique id for the new dropdown instance. For example "some menu".
|
||||
* @param {Object} s Optional settings object for the control.
|
||||
* @param {Object} cc Optional control class to use instead of the default one.
|
||||
@@ -177,12 +180,17 @@
|
||||
// Fix for bug #1897785, #1898007
|
||||
if (tinymce.isIE) {
|
||||
c.onShowMenu.add(function() {
|
||||
// IE 8 needs focus in order to store away a range with the current collapsed caret location
|
||||
ed.focus();
|
||||
|
||||
bm = ed.selection.getBookmark(1);
|
||||
});
|
||||
|
||||
c.onHideMenu.add(function() {
|
||||
if (bm)
|
||||
if (bm) {
|
||||
ed.selection.moveToBookmark(bm);
|
||||
bm = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -193,6 +201,7 @@
|
||||
* Creates a list box control instance by id. A list box is either a native select element or a DOM/JS based list box control. This
|
||||
* depends on the use_native_selects settings state.
|
||||
*
|
||||
* @method createListBox
|
||||
* @param {String} id Unique id for the new listbox instance. For example "styles".
|
||||
* @param {Object} s Optional settings object for the control.
|
||||
* @param {Object} cc Optional control class to use instead of the default one.
|
||||
@@ -236,7 +245,7 @@
|
||||
c.onPostRender.add(function(c, n) {
|
||||
// Store bookmark on mousedown
|
||||
Event.add(n, 'mousedown', function() {
|
||||
ed.bookmark = ed.selection.getBookmark('simple');
|
||||
ed.bookmark = ed.selection.getBookmark(1);
|
||||
});
|
||||
|
||||
// Restore on focus, since it might be lost
|
||||
@@ -256,6 +265,7 @@
|
||||
/**
|
||||
* Creates a button control instance by id.
|
||||
*
|
||||
* @method createButton
|
||||
* @param {String} id Unique id for the new button instance. For example "bold".
|
||||
* @param {Object} s Optional settings object for the control.
|
||||
* @param {Object} cc Optional control class to use instead of the default one.
|
||||
@@ -302,6 +312,7 @@
|
||||
/**
|
||||
* Creates a menu button control instance by id.
|
||||
*
|
||||
* @method createMenuButton
|
||||
* @param {String} id Unique id for the new menu button instance. For example "menu1".
|
||||
* @param {Object} s Optional settings object for the control.
|
||||
* @param {Object} cc Optional control class to use instead of the default one.
|
||||
@@ -317,6 +328,7 @@
|
||||
/**
|
||||
* Creates a split button control instance by id.
|
||||
*
|
||||
* @method createSplitButton
|
||||
* @param {String} id Unique id for the new split button instance. For example "spellchecker".
|
||||
* @param {Object} s Optional settings object for the control.
|
||||
* @param {Object} cc Optional control class to use instead of the default one.
|
||||
@@ -361,6 +373,7 @@
|
||||
/**
|
||||
* Creates a color split button control instance by id.
|
||||
*
|
||||
* @method createColorSplitButton
|
||||
* @param {String} id Unique id for the new color split button instance. For example "forecolor".
|
||||
* @param {Object} s Optional settings object for the control.
|
||||
* @param {Object} cc Optional control class to use instead of the default one.
|
||||
@@ -377,6 +390,9 @@
|
||||
|
||||
if (!s.onclick) {
|
||||
s.onclick = function(v) {
|
||||
if (tinymce.isIE)
|
||||
bm = ed.selection.getBookmark(1);
|
||||
|
||||
ed.execCommand(s.cmd, s.ui || false, v || s.value);
|
||||
};
|
||||
}
|
||||
@@ -408,6 +424,8 @@
|
||||
// Fix for bug #1897785, #1898007
|
||||
if (tinymce.isIE) {
|
||||
c.onShowMenu.add(function() {
|
||||
// IE 8 needs focus in order to store away a range with the current collapsed caret location
|
||||
ed.focus();
|
||||
bm = ed.selection.getBookmark(1);
|
||||
});
|
||||
|
||||
@@ -425,6 +443,7 @@
|
||||
/**
|
||||
* Creates a toolbar container control instance by id.
|
||||
*
|
||||
* @method createToolbar
|
||||
* @param {String} id Unique id for the new toolbar container control instance. For example "toolbar1".
|
||||
* @param {Object} s Optional settings object for the control.
|
||||
* @param {Object} cc Optional control class to use instead of the default one.
|
||||
@@ -446,6 +465,7 @@
|
||||
/**
|
||||
* Creates a separator control instance.
|
||||
*
|
||||
* @method createSeparator
|
||||
* @param {Object} cc Optional control class to use instead of the default one.
|
||||
* @return {tinymce.ui.Control} Control instance that got created and added.
|
||||
*/
|
||||
@@ -458,6 +478,7 @@
|
||||
/**
|
||||
* Overrides a specific control type with a custom class.
|
||||
*
|
||||
* @method setControlType
|
||||
* @param {string} n Name of the control to override for example button or dropmenu.
|
||||
* @param {function} c Class reference to use instead of the default one.
|
||||
* @return {function} Same as the class reference.
|
||||
@@ -465,7 +486,12 @@
|
||||
setControlType : function(n, c) {
|
||||
return this._cls[n.toLowerCase()] = c;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Destroy.
|
||||
*
|
||||
* @method destroy
|
||||
*/
|
||||
destroy : function() {
|
||||
each(this.controls, function(c) {
|
||||
c.destroy();
|
||||
@@ -473,7 +499,5 @@
|
||||
|
||||
this.controls = null;
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
+553
-239
File diff suppressed because it is too large
Load Diff
+130
-370
@@ -1,17 +1,13 @@
|
||||
/**
|
||||
* $Id: EditorCommands.js 958 2008-11-05 13:13:58Z spocke $
|
||||
* $Id: EditorCommands.js 1070 2009-04-01 18:03:06Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var each = tinymce.each, isIE = tinymce.isIE, isGecko = tinymce.isGecko, isOpera = tinymce.isOpera, isWebKit = tinymce.isWebKit;
|
||||
|
||||
function isBlock(n) {
|
||||
return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n.nodeName);
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a internal class and no method in this class should be called directly form the out side.
|
||||
*/
|
||||
@@ -24,23 +20,6 @@
|
||||
var t = this, ed = t.editor, f;
|
||||
|
||||
switch (cmd) {
|
||||
case 'Cut':
|
||||
case 'Copy':
|
||||
case 'Paste':
|
||||
try {
|
||||
ed.getDoc().execCommand(cmd, ui, val);
|
||||
} catch (ex) {
|
||||
if (isGecko) {
|
||||
ed.windowManager.confirm(ed.getLang('clipboard_msg'), function(s) {
|
||||
if (s)
|
||||
window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal');
|
||||
});
|
||||
} else
|
||||
ed.windowManager.alert(ed.getLang('clipboard_no_support'));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
// Ignore these
|
||||
case 'mceResetDesignMode':
|
||||
case 'mceBeginUndoLevel':
|
||||
@@ -59,11 +38,6 @@
|
||||
t.mceJustify(cmd, cmd.substring(7).toLowerCase());
|
||||
return true;
|
||||
|
||||
case 'mceEndUndoLevel':
|
||||
case 'mceAddUndoLevel':
|
||||
ed.undoManager.add();
|
||||
return true;
|
||||
|
||||
default:
|
||||
f = this[cmd];
|
||||
|
||||
@@ -85,7 +59,7 @@
|
||||
iv = parseInt(iv);
|
||||
|
||||
if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {
|
||||
each(this._getSelectedBlocks(), function(e) {
|
||||
each(s.getSelectedBlocks(), function(e) {
|
||||
d.setStyle(e, 'paddingLeft', (parseInt(e.style.paddingLeft || 0) + iv) + iu);
|
||||
});
|
||||
|
||||
@@ -112,7 +86,7 @@
|
||||
iv = parseInt(iv);
|
||||
|
||||
if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {
|
||||
each(this._getSelectedBlocks(), function(e) {
|
||||
each(s.getSelectedBlocks(), function(e) {
|
||||
v = Math.max(0, parseInt(e.style.paddingLeft || 0) - iv);
|
||||
d.setStyle(e, 'paddingLeft', v ? v + iu : '');
|
||||
});
|
||||
@@ -123,13 +97,14 @@
|
||||
ed.getDoc().execCommand('Outdent', false, null);
|
||||
},
|
||||
|
||||
/*
|
||||
mceSetAttribute : function(u, v) {
|
||||
var ed = this.editor, d = ed.dom, e;
|
||||
|
||||
if (e = d.getParent(ed.selection.getNode(), d.isBlock))
|
||||
d.setAttrib(e, v.name, v.value);
|
||||
},
|
||||
|
||||
*/
|
||||
mceSetContent : function(u, v) {
|
||||
this.editor.setContent(v);
|
||||
},
|
||||
@@ -148,7 +123,7 @@
|
||||
},
|
||||
|
||||
mceInsertLink : function(u, v) {
|
||||
var ed = this.editor, s = ed.selection, e = ed.dom.getParent(s.getNode(), 'A');
|
||||
var ed = this.editor, s = ed.selection, e = ed.dom.getParent(s.getNode(), 'a');
|
||||
|
||||
if (tinymce.is(v, 'string'))
|
||||
v = {href : v};
|
||||
@@ -161,9 +136,8 @@
|
||||
|
||||
if (!e) {
|
||||
ed.execCommand('CreateLink', false, 'javascript:mctmp(0);');
|
||||
each(ed.dom.select('a'), function(e) {
|
||||
if (e.href == 'javascript:mctmp(0);')
|
||||
set(e);
|
||||
each(ed.dom.select('a[href=javascript:mctmp(0);]'), function(e) {
|
||||
set(e);
|
||||
});
|
||||
} else {
|
||||
if (v.href)
|
||||
@@ -189,8 +163,6 @@
|
||||
if (!v) {
|
||||
if (s.isCollapsed())
|
||||
s.select(s.getNode());
|
||||
|
||||
t.RemoveFormat();
|
||||
} else {
|
||||
if (ed.settings.convert_fonts_to_spans)
|
||||
t._applyInlineStyle('span', {style : {fontFamily : v}});
|
||||
@@ -266,11 +238,11 @@
|
||||
queryValueFontSize : function() {
|
||||
var ed = this.editor, v = 0, p;
|
||||
|
||||
if (p = ed.dom.getParent(ed.selection.getNode(), 'SPAN'))
|
||||
if (p = ed.dom.getParent(ed.selection.getNode(), 'span'))
|
||||
v = p.style.fontSize;
|
||||
|
||||
if (!v && (isOpera || isWebKit)) {
|
||||
if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))
|
||||
if (p = ed.dom.getParent(ed.selection.getNode(), 'font'))
|
||||
v = p.size;
|
||||
|
||||
return v;
|
||||
@@ -282,10 +254,10 @@
|
||||
queryValueFontName : function() {
|
||||
var ed = this.editor, v = 0, p;
|
||||
|
||||
if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))
|
||||
if (p = ed.dom.getParent(ed.selection.getNode(), 'font'))
|
||||
v = p.face;
|
||||
|
||||
if (p = ed.dom.getParent(ed.selection.getNode(), 'SPAN'))
|
||||
if (p = ed.dom.getParent(ed.selection.getNode(), 'span'))
|
||||
v = p.style.fontFamily.replace(/, /g, ',').replace(/[\'\"]/g, '').toLowerCase();
|
||||
|
||||
if (!v)
|
||||
@@ -350,7 +322,7 @@
|
||||
if (rm)
|
||||
v = '';
|
||||
|
||||
each(this._getSelectedBlocks(dom.getParent(se.getStart(), dom.isBlock), dom.getParent(se.getEnd(), dom.isBlock)), function(e) {
|
||||
each(se.getSelectedBlocks(dom.getParent(se.getStart(), dom.isBlock), dom.getParent(se.getEnd(), dom.isBlock)), function(e) {
|
||||
dom.setAttrib(e, 'align', '');
|
||||
dom.setStyle(e, 'textAlign', v == 'full' ? 'justify' : v);
|
||||
});
|
||||
@@ -421,7 +393,7 @@
|
||||
}
|
||||
} else {
|
||||
function getParent(n) {
|
||||
return dom.getParent(n, function(n) {return n.nodeType == 1;});
|
||||
return dom.getParent(n, '*');
|
||||
};
|
||||
|
||||
sc = r.startContainer;
|
||||
@@ -479,27 +451,6 @@
|
||||
return null;
|
||||
},
|
||||
|
||||
InsertHorizontalRule : function() {
|
||||
// Fix for Gecko <hr size="1" /> issue and IE bug rep(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");
|
||||
if (isGecko || isIE)
|
||||
this.editor.selection.setContent('<hr />');
|
||||
else
|
||||
this.editor.getDoc().execCommand('InsertHorizontalRule', false, '');
|
||||
},
|
||||
|
||||
RemoveFormat : function() {
|
||||
var t = this, ed = t.editor, s = ed.selection, b;
|
||||
|
||||
// Safari breaks tables
|
||||
if (isWebKit)
|
||||
s.setContent(s.getContent({format : 'raw'}).replace(/(<(span|b|i|strong|em|strike) [^>]+>|<(span|b|i|strong|em|strike)>|<\/(span|b|i|strong|em|strike)>|)/g, ''), {format : 'raw'});
|
||||
else
|
||||
ed.getDoc().execCommand('RemoveFormat', false, null);
|
||||
|
||||
t.mceSetStyleInfo(0, {command : 'removeformat'});
|
||||
ed.addVisual();
|
||||
},
|
||||
|
||||
mceSetStyleInfo : function(u, v) {
|
||||
var t = this, ed = t.editor, d = ed.getDoc(), dom = ed.dom, e, b, s = ed.selection, nn = v.wrapper || 'span', b = s.getBookmark(), re;
|
||||
|
||||
@@ -529,7 +480,7 @@
|
||||
else {
|
||||
// Generate wrappers and set styles on them
|
||||
d.execCommand('FontName', false, '__');
|
||||
each(isWebKit ? dom.select('span') : dom.select('font'), function(n) {
|
||||
each(dom.select('span,font'), function(n) {
|
||||
var sp, e;
|
||||
|
||||
if (dom.getAttrib(n, 'face') == '__' || n.style.fontFamily === '__') {
|
||||
@@ -553,9 +504,7 @@
|
||||
// Check if it's an old span in a new wrapper
|
||||
if (!dom.getAttrib(n, 'mce_new')) {
|
||||
// Find new wrapper
|
||||
p = dom.getParent(n, function(n) {
|
||||
return n.nodeType == 1 && dom.getAttrib(n, 'mce_new');
|
||||
});
|
||||
p = dom.getParent(n, '*[mce_new]');
|
||||
|
||||
if (p)
|
||||
dom.remove(n, 1);
|
||||
@@ -658,26 +607,6 @@
|
||||
d.execCommand('BackColor', false, val);
|
||||
},
|
||||
|
||||
Undo : function() {
|
||||
var ed = this.editor;
|
||||
|
||||
if (ed.settings.custom_undo_redo) {
|
||||
ed.undoManager.undo();
|
||||
ed.nodeChanged();
|
||||
} else
|
||||
ed.getDoc().execCommand('Undo', false, null);
|
||||
},
|
||||
|
||||
Redo : function() {
|
||||
var ed = this.editor;
|
||||
|
||||
if (ed.settings.custom_undo_redo) {
|
||||
ed.undoManager.redo();
|
||||
ed.nodeChanged();
|
||||
} else
|
||||
ed.getDoc().execCommand('Redo', false, null);
|
||||
},
|
||||
|
||||
FormatBlock : function(ui, val) {
|
||||
var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, bl, nb, b;
|
||||
|
||||
@@ -819,213 +748,15 @@
|
||||
return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';});
|
||||
},
|
||||
|
||||
mceBlockQuote : function() {
|
||||
var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, sb, eb, n, bm, bq, r, bq2, i, nl;
|
||||
|
||||
function getBQ(e) {
|
||||
return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});
|
||||
};
|
||||
|
||||
// Get start/end block
|
||||
sb = dom.getParent(s.getStart(), isBlock);
|
||||
eb = dom.getParent(s.getEnd(), isBlock);
|
||||
|
||||
// Remove blockquote(s)
|
||||
if (bq = getBQ(sb)) {
|
||||
if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))
|
||||
bm = s.getBookmark();
|
||||
|
||||
// Move all elements after the end block into new bq
|
||||
if (getBQ(eb)) {
|
||||
bq2 = bq.cloneNode(false);
|
||||
|
||||
while (n = eb.nextSibling)
|
||||
bq2.appendChild(n.parentNode.removeChild(n));
|
||||
}
|
||||
|
||||
// Add new bq after
|
||||
if (bq2)
|
||||
dom.insertAfter(bq2, bq);
|
||||
|
||||
// Move all selected blocks after the current bq
|
||||
nl = t._getSelectedBlocks(sb, eb);
|
||||
for (i = nl.length - 1; i >= 0; i--) {
|
||||
dom.insertAfter(nl[i], bq);
|
||||
}
|
||||
|
||||
// Empty bq, then remove it
|
||||
if (/^\s*$/.test(bq.innerHTML))
|
||||
dom.remove(bq, 1); // Keep children so boomark restoration works correctly
|
||||
|
||||
// Empty bq, then remote it
|
||||
if (bq2 && /^\s*$/.test(bq2.innerHTML))
|
||||
dom.remove(bq2, 1); // Keep children so boomark restoration works correctly
|
||||
|
||||
if (!bm) {
|
||||
// Move caret inside empty block element
|
||||
if (!isIE) {
|
||||
r = ed.getDoc().createRange();
|
||||
r.setStart(sb, 0);
|
||||
r.setEnd(sb, 0);
|
||||
s.setRng(r);
|
||||
} else {
|
||||
s.select(sb);
|
||||
s.collapse(0);
|
||||
|
||||
// IE misses the empty block some times element so we must move back the caret
|
||||
if (dom.getParent(s.getStart(), isBlock) != sb) {
|
||||
r = s.getRng();
|
||||
r.move('character', -1);
|
||||
r.select();
|
||||
}
|
||||
}
|
||||
} else
|
||||
t.editor.selection.moveToBookmark(bm);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Since IE can start with a totally empty document we need to add the first bq and paragraph
|
||||
if (isIE && !sb && !eb) {
|
||||
t.editor.getDoc().execCommand('Indent');
|
||||
n = getBQ(s.getNode());
|
||||
n.style.margin = n.dir = ''; // IE adds margin and dir to bq
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sb || !eb)
|
||||
return;
|
||||
|
||||
// If empty paragraph node then do not use bookmark
|
||||
if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))
|
||||
bm = s.getBookmark();
|
||||
|
||||
// Move selected block elements into a bq
|
||||
each(t._getSelectedBlocks(getBQ(s.getStart()), getBQ(s.getEnd())), function(e) {
|
||||
// Found existing BQ add to this one
|
||||
if (e.nodeName == 'BLOCKQUOTE' && !bq) {
|
||||
bq = e;
|
||||
return;
|
||||
}
|
||||
|
||||
// No BQ found, create one
|
||||
if (!bq) {
|
||||
bq = dom.create('blockquote');
|
||||
e.parentNode.insertBefore(bq, e);
|
||||
}
|
||||
|
||||
// Add children from existing BQ
|
||||
if (e.nodeName == 'BLOCKQUOTE' && bq) {
|
||||
n = e.firstChild;
|
||||
|
||||
while (n) {
|
||||
bq.appendChild(n.cloneNode(true));
|
||||
n = n.nextSibling;
|
||||
}
|
||||
|
||||
dom.remove(e);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add non BQ element to BQ
|
||||
bq.appendChild(dom.remove(e));
|
||||
});
|
||||
|
||||
if (!bm) {
|
||||
// Move caret inside empty block element
|
||||
if (!isIE) {
|
||||
r = ed.getDoc().createRange();
|
||||
r.setStart(sb, 0);
|
||||
r.setEnd(sb, 0);
|
||||
s.setRng(r);
|
||||
} else {
|
||||
s.select(sb);
|
||||
s.collapse(1);
|
||||
}
|
||||
} else
|
||||
s.moveToBookmark(bm);
|
||||
},
|
||||
|
||||
_applyInlineStyle : function(na, at, op) {
|
||||
var t = this, ed = t.editor, dom = ed.dom, bm, lo = {}, kh;
|
||||
var t = this, ed = t.editor, dom = ed.dom, bm, lo = {}, kh, found;
|
||||
|
||||
na = na.toUpperCase();
|
||||
|
||||
if (op && op.check_classes && at['class'])
|
||||
op.check_classes.push(at['class']);
|
||||
|
||||
function replaceFonts() {
|
||||
var bm;
|
||||
|
||||
each(dom.select(tinymce.isWebKit && !tinymce.isAir ? 'span' : 'font'), function(n) {
|
||||
if (n.style.fontFamily == 'mceinline' || n.face == 'mceinline') {
|
||||
if (!bm)
|
||||
bm = ed.selection.getBookmark();
|
||||
|
||||
at._mce_new = '1';
|
||||
dom.replace(dom.create(na, at), n, 1);
|
||||
}
|
||||
});
|
||||
|
||||
// Remove redundant elements
|
||||
each(dom.select(na), function(n) {
|
||||
if (n.getAttribute('_mce_new')) {
|
||||
function removeStyle(n) {
|
||||
if (n.nodeType == 1) {
|
||||
each(at.style, function(v, k) {
|
||||
dom.setStyle(n, k, '');
|
||||
});
|
||||
|
||||
// Remove spans with the same class or marked classes
|
||||
if (at['class'] && n.className && op) {
|
||||
each(op.check_classes, function(c) {
|
||||
if (dom.hasClass(n, c))
|
||||
dom.removeClass(n, c);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Remove specified style information from child elements
|
||||
each(dom.select(na, n), removeStyle);
|
||||
|
||||
// Remove the specified style information on parent if current node is only child (IE)
|
||||
if (n.parentNode && n.parentNode.nodeType == 1 && n.parentNode.childNodes.length == 1)
|
||||
removeStyle(n.parentNode);
|
||||
|
||||
// Remove the child elements style info if a parent already has it
|
||||
dom.getParent(n.parentNode, function(pn) {
|
||||
if (pn.nodeType == 1) {
|
||||
if (at.style) {
|
||||
each(at.style, function(v, k) {
|
||||
var sv;
|
||||
|
||||
if (!lo[k] && (sv = dom.getStyle(pn, k))) {
|
||||
if (sv === v)
|
||||
dom.setStyle(n, k, '');
|
||||
|
||||
lo[k] = 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Remove spans with the same class or marked classes
|
||||
if (at['class'] && pn.className && op) {
|
||||
each(op.check_classes, function(c) {
|
||||
if (dom.hasClass(pn, c))
|
||||
dom.removeClass(n, c);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
n.removeAttribute('_mce_new');
|
||||
}
|
||||
});
|
||||
|
||||
// Remove empty span elements
|
||||
function removeEmpty() {
|
||||
each(dom.select(na).reverse(), function(n) {
|
||||
var c = 0;
|
||||
|
||||
@@ -1041,7 +772,78 @@
|
||||
if (c == 0)
|
||||
dom.remove(n, 1);
|
||||
});
|
||||
};
|
||||
|
||||
function replaceFonts() {
|
||||
var bm;
|
||||
|
||||
each(dom.select('span,font'), function(n) {
|
||||
if (n.style.fontFamily == 'mceinline' || n.face == 'mceinline') {
|
||||
if (!bm)
|
||||
bm = ed.selection.getBookmark();
|
||||
|
||||
at._mce_new = '1';
|
||||
dom.replace(dom.create(na, at), n, 1);
|
||||
}
|
||||
});
|
||||
|
||||
// Remove redundant elements
|
||||
each(dom.select(na + '[_mce_new]'), function(n) {
|
||||
function removeStyle(n) {
|
||||
if (n.nodeType == 1) {
|
||||
each(at.style, function(v, k) {
|
||||
dom.setStyle(n, k, '');
|
||||
});
|
||||
|
||||
// Remove spans with the same class or marked classes
|
||||
if (at['class'] && n.className && op) {
|
||||
each(op.check_classes, function(c) {
|
||||
if (dom.hasClass(n, c))
|
||||
dom.removeClass(n, c);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Remove specified style information from child elements
|
||||
each(dom.select(na, n), removeStyle);
|
||||
|
||||
// Remove the specified style information on parent if current node is only child (IE)
|
||||
if (n.parentNode && n.parentNode.nodeType == 1 && n.parentNode.childNodes.length == 1)
|
||||
removeStyle(n.parentNode);
|
||||
|
||||
// Remove the child elements style info if a parent already has it
|
||||
dom.getParent(n.parentNode, function(pn) {
|
||||
if (pn.nodeType == 1) {
|
||||
if (at.style) {
|
||||
each(at.style, function(v, k) {
|
||||
var sv;
|
||||
|
||||
if (!lo[k] && (sv = dom.getStyle(pn, k))) {
|
||||
if (sv === v)
|
||||
dom.setStyle(n, k, '');
|
||||
|
||||
lo[k] = 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Remove spans with the same class or marked classes
|
||||
if (at['class'] && pn.className && op) {
|
||||
each(op.check_classes, function(c) {
|
||||
if (dom.hasClass(pn, c))
|
||||
dom.removeClass(n, c);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
n.removeAttribute('_mce_new');
|
||||
});
|
||||
|
||||
removeEmpty();
|
||||
ed.selection.moveToBookmark(bm);
|
||||
|
||||
return !!bm;
|
||||
@@ -1060,6 +862,45 @@
|
||||
}
|
||||
|
||||
if (ed.selection.isCollapsed()) {
|
||||
// IE will format the current word so this code can't be executed on that browser
|
||||
if (!isIE) {
|
||||
each(dom.getParents(ed.selection.getNode(), 'span'), function(n) {
|
||||
each(at.style, function(v, k) {
|
||||
var kv;
|
||||
|
||||
if (kv = dom.getStyle(n, k)) {
|
||||
if (kv == v) {
|
||||
dom.setStyle(n, k, '');
|
||||
found = 2;
|
||||
return false;
|
||||
}
|
||||
|
||||
found = 1;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (found)
|
||||
return false;
|
||||
});
|
||||
|
||||
if (found == 2) {
|
||||
bm = ed.selection.getBookmark();
|
||||
|
||||
removeEmpty();
|
||||
|
||||
ed.selection.moveToBookmark(bm);
|
||||
|
||||
// Node change needs to be detached since the onselect event
|
||||
// for the select box will run the onclick handler after onselect call. Todo: Add a nicer fix!
|
||||
window.setTimeout(function() {
|
||||
ed.nodeChanged();
|
||||
}, 1);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Start collecting styles
|
||||
t._pendingStyles = tinymce.extend(t._pendingStyles || {}, at.style);
|
||||
|
||||
@@ -1088,87 +929,6 @@
|
||||
ed.onKeyUp.add(kh);
|
||||
} else
|
||||
t._pendingStyles = 0;
|
||||
},
|
||||
|
||||
/*
|
||||
_mceBlockQuote : function() {
|
||||
var t = this, s = t.editor.selection, b = s.getBookmark(), bq, dom = t.editor.dom;
|
||||
|
||||
function findBQ(e) {
|
||||
return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});
|
||||
};
|
||||
|
||||
// Remove blockquote(s)
|
||||
if (findBQ(s.getStart())) {
|
||||
each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {
|
||||
// Found BQ lets remove it
|
||||
if (e.nodeName == 'BLOCKQUOTE')
|
||||
dom.remove(e, 1);
|
||||
});
|
||||
|
||||
t.editor.selection.moveToBookmark(b);
|
||||
return;
|
||||
}
|
||||
|
||||
each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {
|
||||
var n;
|
||||
|
||||
// Found existing BQ add to this one
|
||||
if (e.nodeName == 'BLOCKQUOTE' && !bq) {
|
||||
bq = e;
|
||||
return;
|
||||
}
|
||||
|
||||
// No BQ found, create one
|
||||
if (!bq) {
|
||||
bq = dom.create('blockquote');
|
||||
e.parentNode.insertBefore(bq, e);
|
||||
}
|
||||
|
||||
// Add children from existing BQ
|
||||
if (e.nodeName == 'BLOCKQUOTE' && bq) {
|
||||
n = e.firstChild;
|
||||
|
||||
while (n) {
|
||||
bq.appendChild(n.cloneNode(true));
|
||||
n = n.nextSibling;
|
||||
}
|
||||
|
||||
dom.remove(e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Add non BQ element to BQ
|
||||
bq.appendChild(dom.remove(e));
|
||||
});
|
||||
|
||||
t.editor.selection.moveToBookmark(b);
|
||||
},
|
||||
*/
|
||||
_getSelectedBlocks : function(st, en) {
|
||||
var ed = this.editor, dom = ed.dom, s = ed.selection, sb, eb, n, bl = [];
|
||||
|
||||
sb = dom.getParent(st || s.getStart(), isBlock);
|
||||
eb = dom.getParent(en || s.getEnd(), isBlock);
|
||||
|
||||
if (sb)
|
||||
bl.push(sb);
|
||||
|
||||
if (sb && eb && sb != eb) {
|
||||
n = sb;
|
||||
|
||||
while ((n = n.nextSibling) && n != eb) {
|
||||
if (isBlock(n))
|
||||
bl.push(n);
|
||||
}
|
||||
}
|
||||
|
||||
if (eb && sb != eb)
|
||||
bl.push(eb);
|
||||
|
||||
return bl;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
})(tinymce);
|
||||
+52
-32
@@ -1,31 +1,44 @@
|
||||
/**
|
||||
* $Id: EditorManager.js 920 2008-09-09 14:05:33Z spocke $
|
||||
* $Id: EditorManager.js 1190 2009-08-12 17:59:29Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
// Shorten names
|
||||
var each = tinymce.each, extend = tinymce.extend, DOM = tinymce.DOM, Event = tinymce.dom.Event, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, explode = tinymce.explode;
|
||||
|
||||
/**#@+
|
||||
* @class This class is used to create multiple editor instances and contain them in a collection. So it's both a factory and a manager for editor instances.
|
||||
/**
|
||||
* This class is used to create multiple editor instances and contain them in a collection. So it's both a factory and a manager for editor instances.
|
||||
*
|
||||
* @static
|
||||
* @member tinymce.EditorManager
|
||||
* @class tinymce.EditorManager
|
||||
*/
|
||||
tinymce.create('static tinymce.EditorManager', {
|
||||
editors : {},
|
||||
i18n : {},
|
||||
activeEditor : null,
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
/**
|
||||
* Collection of editor instances.
|
||||
*
|
||||
* @property editors
|
||||
* @type Object
|
||||
*/
|
||||
editors : {},
|
||||
|
||||
i18n : {},
|
||||
|
||||
/**
|
||||
* Currently active editor instance.
|
||||
*
|
||||
* @property activeEditor
|
||||
* @type tinymce.Editor
|
||||
*/
|
||||
activeEditor : null,
|
||||
|
||||
/**
|
||||
* Preinitializes the EditorManager class. This method will be called automatically when the page loads and it
|
||||
* will setup some important paths and URIs and attach some document events.
|
||||
*
|
||||
* @method preInit
|
||||
*/
|
||||
preInit : function() {
|
||||
var t = this, lo = window.location;
|
||||
@@ -38,14 +51,6 @@
|
||||
tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);
|
||||
tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);
|
||||
|
||||
// User already specified a document.domain value
|
||||
if (document.domain && lo.hostname != document.domain)
|
||||
tinymce.relaxedDomain = document.domain;
|
||||
|
||||
// Setup document domain if tinymce is loaded from other domain
|
||||
if (!tinymce.relaxedDomain && tinymce.EditorManager.baseURI.host != lo.hostname && lo.hostname)
|
||||
document.domain = tinymce.relaxedDomain = lo.hostname.replace(/.*\.(.+\..+)$/, '$1');
|
||||
|
||||
// Add before unload listener
|
||||
// This was required since IE was leaking memory if you added and removed beforeunload listeners
|
||||
// with attachEvent/detatchEvent so this only adds one listener and instances can the attach to the onBeforeUnload event
|
||||
@@ -60,6 +65,7 @@
|
||||
/**
|
||||
* Initializes a set of editors. This method will create a bunch of editors based in the input.
|
||||
*
|
||||
* @method init
|
||||
* @param {Object} s Settings object to be passed to each editor instance.
|
||||
*/
|
||||
init : function(s) {
|
||||
@@ -102,10 +108,6 @@
|
||||
if (s.plugins) {
|
||||
pl = explode(s.plugins);
|
||||
|
||||
// Load compat2x first
|
||||
if (tinymce.inArray(pl, 'compat2x') != -1)
|
||||
PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');
|
||||
|
||||
// Load rest if plugins
|
||||
each(pl, function(v) {
|
||||
if (v && v.charAt(0) != '-' && !PluginManager.urls[v]) {
|
||||
@@ -251,6 +253,7 @@
|
||||
/**
|
||||
* Returns a editor instance by id.
|
||||
*
|
||||
* @method get
|
||||
* @param {String} id Editor instance id to return.
|
||||
* @return {tinymce.Editor} Editor instance to return.
|
||||
*/
|
||||
@@ -261,16 +264,20 @@
|
||||
/**
|
||||
* Returns a editor instance by id. This method was added for compatibility with the 2.x branch.
|
||||
*
|
||||
* @method getInstanceById
|
||||
* @param {String} id Editor instance id to return.
|
||||
* @return {tinymce.Editor} Editor instance to return.
|
||||
* @deprecated Use get method instead.
|
||||
* @see #get
|
||||
*/
|
||||
getInstanceById : function(id) {
|
||||
return this.get(id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds an editor instance to the editor colleciton. This will also set it as the active editor.
|
||||
* Adds an editor instance to the editor collection. This will also set it as the active editor.
|
||||
*
|
||||
* @method add
|
||||
* @param {tinymce.Editor} e Editor instance to add to the collection.
|
||||
* @return {tinymce.Editor} The same instance that got passed in.
|
||||
*/
|
||||
@@ -284,6 +291,7 @@
|
||||
/**
|
||||
* Removes a editor instance from the collection.
|
||||
*
|
||||
* @method remove
|
||||
* @param {tinymce.Editor} e Editor instance to remove.
|
||||
* @return {tinymce.Editor} The editor that got passed in will be return if it was found otherwise null.
|
||||
*/
|
||||
@@ -298,6 +306,8 @@
|
||||
|
||||
// Select another editor since the active one was removed
|
||||
if (t.activeEditor == e) {
|
||||
t._setActive(null);
|
||||
|
||||
each(t.editors, function(e) {
|
||||
t._setActive(e);
|
||||
return false; // Break
|
||||
@@ -312,10 +322,11 @@
|
||||
/**
|
||||
* Executes a specific command on the currently active editor.
|
||||
*
|
||||
* @method execCommand
|
||||
* @param {String} c Command to perform for example Bold.
|
||||
* @param {bool} u Optional boolean state if a UI should be presented for the command or not.
|
||||
* @param {Boolean} u Optional boolean state if a UI should be presented for the command or not.
|
||||
* @param {String} v Optional value parameter like for example an URL to a link.
|
||||
* @return {bool} true/false if the command was executed or not.
|
||||
* @return {Boolean} true/false if the command was executed or not.
|
||||
*/
|
||||
execCommand : function(c, u, v) {
|
||||
var t = this, ed = t.get(v), w;
|
||||
@@ -392,11 +403,13 @@
|
||||
/**
|
||||
* Executes a command on a specific editor by id. This method was added for compatibility with the 2.x branch.
|
||||
*
|
||||
* @deprecated Use the execCommand method of a editor instance instead.
|
||||
* @method execInstanceCommand
|
||||
* @param {String} id Editor id to perform the command on.
|
||||
* @param {String} c Command to perform for example Bold.
|
||||
* @param {bool} u Optional boolean state if a UI should be presented for the command or not.
|
||||
* @param {Boolean} u Optional boolean state if a UI should be presented for the command or not.
|
||||
* @param {String} v Optional value parameter like for example an URL to a link.
|
||||
* @return {bool} true/false if the command was executed or not.
|
||||
* @return {Boolean} true/false if the command was executed or not.
|
||||
*/
|
||||
execInstanceCommand : function(id, c, u, v) {
|
||||
var ed = this.get(id);
|
||||
@@ -409,6 +422,8 @@
|
||||
|
||||
/**
|
||||
* Calls the save method on all editor instances in the collection. This can be useful when a form is to be submitted.
|
||||
*
|
||||
* @method triggerSave
|
||||
*/
|
||||
triggerSave : function() {
|
||||
each(this.editors, function(e) {
|
||||
@@ -419,6 +434,7 @@
|
||||
/**
|
||||
* Adds a language pack, this gets called by the loaded language files like en.js.
|
||||
*
|
||||
* @method addI18n
|
||||
* @param {String} p Prefix for the language items. For example en.myplugin
|
||||
* @param {Object} o Name/Value collection with items to add to the language group.
|
||||
*/
|
||||
@@ -448,12 +464,16 @@
|
||||
_setActive : function(e) {
|
||||
this.selectedInstance = this.activeEditor = e;
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
|
||||
tinymce.EditorManager.preInit();
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
// Short for editor manager window.tinyMCE is needed when TinyMCE gets loaded though a XHR call
|
||||
/**
|
||||
* Shorter version of tinymce.EditorManager also added for 2.x compatibility.
|
||||
*
|
||||
* @member
|
||||
* @property tinyMCE
|
||||
* @type tinymce.EditorManager
|
||||
*/
|
||||
var tinyMCE = window.tinyMCE = tinymce.EditorManager;
|
||||
|
||||
+124
-48
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
* $Id: ForceBlocks.js 941 2008-10-23 18:11:02Z spocke $
|
||||
* $Id: ForceBlocks.js 1232 2009-09-21 19:04:13Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
// Shorten names
|
||||
var Event, isIE, isGecko, isOpera, each, extend;
|
||||
|
||||
@@ -16,6 +16,26 @@
|
||||
each = tinymce.each;
|
||||
extend = tinymce.extend;
|
||||
|
||||
// Checks if the selection/caret is at the end of the specified block element
|
||||
function isAtEnd(rng, par) {
|
||||
var rng2 = par.ownerDocument.createRange();
|
||||
|
||||
rng2.setStart(rng.endContainer, rng.endOffset);
|
||||
rng2.setEndAfter(par);
|
||||
|
||||
// Get number of characters to the right of the cursor if it's zero then we are at the end and need to merge the next block element
|
||||
return rng2.cloneContents().textContent.length == 0;
|
||||
};
|
||||
|
||||
function isEmpty(n) {
|
||||
n = n.innerHTML;
|
||||
|
||||
n = n.replace(/<(img|hr|table|input|select|textarea)[ \>]/gi, '-'); // Keep these convert them to - chars
|
||||
n = n.replace(/<[^>]+>/g, ''); // Remove all tags
|
||||
|
||||
return n.replace(/[ \t\r\n]+/g, '') == '';
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a internal class and no method in this class should be called directly form the out side.
|
||||
*/
|
||||
@@ -33,9 +53,8 @@
|
||||
t.reOpera = new RegExp('(\\u00a0| | )<\/' + elm + '>', 'gi');
|
||||
t.rePadd = new RegExp('<p( )([^>]+)><\\\/p>|<p( )([^>]+)\\\/>|<p( )([^>]+)>\\s+<\\\/p>|<p><\\\/p>|<p\\\/>|<p>\\s+<\\\/p>'.replace(/p/g, elm), 'gi');
|
||||
t.reNbsp2BR1 = new RegExp('<p( )([^>]+)>[\\s\\u00a0]+<\\\/p>|<p>[\\s\\u00a0]+<\\\/p>'.replace(/p/g, elm), 'gi');
|
||||
t.reNbsp2BR2 = new RegExp('<p( )([^>]+)>( | )<\\\/p>|<p>( | )<\\\/p>'.replace(/p/g, elm), 'gi');
|
||||
t.reNbsp2BR2 = new RegExp('<%p()([^>]+)>( | )<\\\/%p>|<%p>( | )<\\\/%p>'.replace(/%p/g, elm), 'gi');
|
||||
t.reBR2Nbsp = new RegExp('<p( )([^>]+)>\\s*<br \\\/>\\s*<\\\/p>|<p>\\s*<br \\\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');
|
||||
t.reTrailBr = new RegExp('\\s*<br \\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');
|
||||
|
||||
function padd(ed, o) {
|
||||
if (isOpera)
|
||||
@@ -47,10 +66,8 @@
|
||||
// Use instead of BR in padded paragraphs
|
||||
o.content = o.content.replace(t.reNbsp2BR1, '<' + elm + '$1$2><br /></' + elm + '>');
|
||||
o.content = o.content.replace(t.reNbsp2BR2, '<' + elm + '$1$2><br /></' + elm + '>');
|
||||
} else {
|
||||
} else
|
||||
o.content = o.content.replace(t.reBR2Nbsp, '<' + elm + '$1$2>\u00a0</' + elm + '>');
|
||||
o.content = o.content.replace(t.reTrailBr, '</' + elm + '>');
|
||||
}
|
||||
};
|
||||
|
||||
ed.onBeforeSetContent.add(padd);
|
||||
@@ -136,29 +153,47 @@
|
||||
return ne;
|
||||
};
|
||||
|
||||
// Replaces IE:s auto generated paragraphs with the specified element name
|
||||
if (isIE && s.element != 'P') {
|
||||
ed.onKeyPress.add(function(ed, e) {
|
||||
t.lastElm = ed.selection.getNode().nodeName;
|
||||
});
|
||||
|
||||
ed.onKeyUp.add(function(ed, e) {
|
||||
var bl, sel = ed.selection, n = sel.getNode(), b = ed.getBody();
|
||||
|
||||
if (b.childNodes.length === 1 && n.nodeName == 'P') {
|
||||
n = ren(n, s.element);
|
||||
sel.select(n);
|
||||
sel.collapse();
|
||||
ed.nodeChanged();
|
||||
} else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') {
|
||||
bl = ed.dom.getParent(n, 'P');
|
||||
|
||||
if (bl) {
|
||||
ren(bl, s.element);
|
||||
ed.nodeChanged();
|
||||
}
|
||||
// Padd empty inline elements within block elements
|
||||
// For example: <p><strong><em></em></strong></p> becomes <p><strong><em> </em></strong></p>
|
||||
ed.onPreProcess.add(function(ed, o) {
|
||||
each(ed.dom.select('p,h1,h2,h3,h4,h5,h6,div', o.node), function(p) {
|
||||
if (isEmpty(p)) {
|
||||
each(ed.dom.select('span,em,strong,b,i', o.node), function(n) {
|
||||
if (!n.hasChildNodes()) {
|
||||
n.appendChild(ed.getDoc().createTextNode('\u00a0'));
|
||||
return false; // Break the loop one padding is enough
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// IE specific fixes
|
||||
if (isIE) {
|
||||
// Replaces IE:s auto generated paragraphs with the specified element name
|
||||
if (s.element != 'P') {
|
||||
ed.onKeyPress.add(function(ed, e) {
|
||||
t.lastElm = ed.selection.getNode().nodeName;
|
||||
});
|
||||
|
||||
ed.onKeyUp.add(function(ed, e) {
|
||||
var bl, sel = ed.selection, n = sel.getNode(), b = ed.getBody();
|
||||
|
||||
if (b.childNodes.length === 1 && n.nodeName == 'P') {
|
||||
n = ren(n, s.element);
|
||||
sel.select(n);
|
||||
sel.collapse();
|
||||
ed.nodeChanged();
|
||||
} else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') {
|
||||
bl = ed.dom.getParent(n, 'p');
|
||||
|
||||
if (bl) {
|
||||
ren(bl, s.element);
|
||||
ed.nodeChanged();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -193,7 +228,7 @@
|
||||
nx = nl[i];
|
||||
|
||||
// Is text or non block element
|
||||
if (nx.nodeType == 3 || (!t.dom.isBlock(nx) && nx.nodeType != 8)) {
|
||||
if (nx.nodeType === 3 || (!t.dom.isBlock(nx) && nx.nodeType !== 8 && !/^(script|mce:script|style|mce:style)$/i.test(nx.nodeName))) {
|
||||
if (!bl) {
|
||||
// Create new block but ignore whitespace
|
||||
if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) {
|
||||
@@ -233,9 +268,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Uses replaceChild instead of cloneNode since it removes selected attribute from option elements on IE
|
||||
// See: http://support.microsoft.com/kb/829907
|
||||
bl = ed.dom.create(ed.settings.forced_root_block);
|
||||
bl.appendChild(nx.cloneNode(1));
|
||||
nx.parentNode.replaceChild(bl, nx);
|
||||
bl.appendChild(nx);
|
||||
}
|
||||
} else {
|
||||
if (bl.hasChildNodes())
|
||||
@@ -306,14 +343,6 @@
|
||||
var t = this, ed = t.editor, dom = ed.dom, d = ed.getDoc(), se = ed.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body;
|
||||
var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n, vp = dom.getViewPort(ed.getWin()), y, ch, car;
|
||||
|
||||
function isEmpty(n) {
|
||||
n = n.innerHTML;
|
||||
n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars
|
||||
n = n.replace(/<[^>]+>/g, ''); // Remove all tags
|
||||
|
||||
return n.replace(/[ \t\r\n]+/g, '') == '';
|
||||
};
|
||||
|
||||
// If root blocks are forced then use Operas default behavior since it's really good
|
||||
// Removed due to bug: #1853816
|
||||
// if (se.forced_root_block && isOpera)
|
||||
@@ -342,11 +371,19 @@
|
||||
|
||||
// If selection is in empty table cell
|
||||
if (sn === en && /^(TD|TH)$/.test(sn.nodeName)) {
|
||||
dom.remove(sn.firstChild); // Remove BR
|
||||
if (sn.firstChild.nodeName == 'BR')
|
||||
dom.remove(sn.firstChild); // Remove BR
|
||||
|
||||
// Create two new block elements
|
||||
ed.dom.add(sn, se.element, null, '<br />');
|
||||
aft = ed.dom.add(sn, se.element, null, '<br />');
|
||||
if (sn.childNodes.length == 0) {
|
||||
ed.dom.add(sn, se.element, null, '<br />');
|
||||
aft = ed.dom.add(sn, se.element, null, '<br />');
|
||||
} else {
|
||||
n = sn.innerHTML;
|
||||
sn.innerHTML = '';
|
||||
ed.dom.add(sn, se.element, null, n);
|
||||
aft = ed.dom.add(sn, se.element, null, '<br />');
|
||||
}
|
||||
|
||||
// Move caret into the last one
|
||||
r = d.createRange();
|
||||
@@ -379,23 +416,23 @@
|
||||
bn = sb ? sb.nodeName : se.element; // Get block name to create
|
||||
|
||||
// Return inside list use default browser behavior
|
||||
if (t.dom.getParent(sb, function(n) { return /OL|UL|PRE/.test(n.nodeName); }))
|
||||
if (t.dom.getParent(sb, 'ol,ul,pre'))
|
||||
return true;
|
||||
|
||||
// If caption or absolute layers then always generate new blocks within
|
||||
if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(sb.style.position))) {
|
||||
if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) {
|
||||
bn = se.element;
|
||||
sb = null;
|
||||
}
|
||||
|
||||
// If caption or absolute layers then always generate new blocks within
|
||||
if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(eb.style.position))) {
|
||||
if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) {
|
||||
bn = se.element;
|
||||
eb = null;
|
||||
}
|
||||
|
||||
// Use P instead
|
||||
if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(sb.style.cssFloat))) {
|
||||
if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(dom.getStyle(sb, 'float', 1)))) {
|
||||
bn = se.element;
|
||||
sb = eb = null;
|
||||
}
|
||||
@@ -408,7 +445,7 @@
|
||||
aft.removeAttribute('id');
|
||||
|
||||
// Is header and cursor is at the end, then force paragraph under
|
||||
if (/^(H[1-6])$/.test(bn) && sn.nodeValue && so == sn.nodeValue.length)
|
||||
if (/^(H[1-6])$/.test(bn) && isAtEnd(r, sb))
|
||||
aft = ed.dom.create(se.element);
|
||||
|
||||
// Find start chop node
|
||||
@@ -553,7 +590,46 @@
|
||||
},
|
||||
|
||||
backspaceDelete : function(e, bs) {
|
||||
var t = this, ed = t.editor, b = ed.getBody(), n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n, w, tn;
|
||||
var t = this, ed = t.editor, b = ed.getBody(), dom = ed.dom, n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n, w, tn;
|
||||
|
||||
/*
|
||||
var par, rng, nextBlock;
|
||||
|
||||
// Delete key will not merge paragraphs on Gecko so we need to do this manually
|
||||
// Hitting the delete key at the following caret position doesn't merge the elements <p>A|</p><p>B</p>
|
||||
// This logic will merge them into this: <p>A|B</p>
|
||||
if (e.keyCode == 46) {
|
||||
if (r.collapsed) {
|
||||
par = dom.getParent(sc, 'p,h1,h2,h3,h4,h5,h6,div');
|
||||
|
||||
if (par) {
|
||||
rng = dom.createRng();
|
||||
|
||||
rng.setStart(sc, r.startOffset);
|
||||
rng.setEndAfter(par);
|
||||
|
||||
// Get number of characters to the right of the cursor if it's zero then we are at the end and need to merge the next block element
|
||||
if (dom.getOuterHTML(rng.cloneContents()).replace(/<[^>]+>/g, '').length == 0) {
|
||||
nextBlock = dom.getNext(par, 'p,h1,h2,h3,h4,h5,h6,div');
|
||||
|
||||
// Copy all children from next sibling block and remove it
|
||||
if (nextBlock) {
|
||||
each(nextBlock.childNodes, function(node) {
|
||||
par.appendChild(node.cloneNode(true));
|
||||
});
|
||||
|
||||
dom.remove(nextBlock);
|
||||
}
|
||||
|
||||
// Block the default even since the Gecko team might eventually fix this
|
||||
// We will remove this logic once they do we can't feature detect this one
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// The caret sometimes gets stuck in Gecko if you delete empty paragraphs
|
||||
// This workaround removes the element by hand and moves the caret to the previous element
|
||||
@@ -617,4 +693,4 @@
|
||||
}, 1);
|
||||
}
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
+1574
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* LegacyInput.js
|
||||
*
|
||||
* Copyright 2009, Moxiecode Systems AB
|
||||
* Released under LGPL License.
|
||||
*
|
||||
* License: http://tinymce.moxiecode.com/license
|
||||
* Contributing: http://tinymce.moxiecode.com/contributing
|
||||
*/
|
||||
|
||||
tinymce.onAddEditor.add(function(tinymce, ed) {
|
||||
var filters, fontSizes, dom, settings = ed.settings;
|
||||
|
||||
if (settings.inline_styles) {
|
||||
fontSizes = tinymce.explode(settings.font_size_style_values);
|
||||
|
||||
function replaceWithSpan(node, styles) {
|
||||
tinymce.each(styles, function(value, name) {
|
||||
if (value)
|
||||
dom.setStyle(node, name, value);
|
||||
});
|
||||
|
||||
dom.rename(node, 'span');
|
||||
};
|
||||
|
||||
filters = {
|
||||
font : function(dom, node) {
|
||||
replaceWithSpan(node, {
|
||||
backgroundColor : node.style.backgroundColor,
|
||||
color : node.color,
|
||||
fontFamily : node.face,
|
||||
fontSize : fontSizes[parseInt(node.size) - 1]
|
||||
});
|
||||
},
|
||||
|
||||
u : function(dom, node) {
|
||||
replaceWithSpan(node, {
|
||||
textDecoration : 'underline'
|
||||
});
|
||||
},
|
||||
|
||||
strike : function(dom, node) {
|
||||
replaceWithSpan(node, {
|
||||
textDecoration : 'line-through'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function convert(editor, params) {
|
||||
dom = editor.dom;
|
||||
|
||||
if (settings.convert_fonts_to_spans) {
|
||||
tinymce.each(dom.select('font,u,strike', params.node), function(node) {
|
||||
filters[node.nodeName.toLowerCase()](ed.dom, node);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ed.onPreProcess.add(convert);
|
||||
|
||||
ed.onInit.add(function() {
|
||||
ed.selection.onSetContent.add(convert);
|
||||
});
|
||||
}
|
||||
});
|
||||
+73
-48
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: Popup.js 920 2008-09-09 14:05:33Z spocke $
|
||||
* $Id: Popup.js 1204 2009-08-19 12:12:07Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
@@ -8,34 +8,22 @@
|
||||
// Some global instances
|
||||
var tinymce = null, tinyMCEPopup, tinyMCE;
|
||||
|
||||
/**#@+
|
||||
* @class TinyMCE popup/dialog helper class. This gives you easy access to the
|
||||
/**
|
||||
* TinyMCE popup/dialog helper class. This gives you easy access to the
|
||||
* parent editor instance and a bunch of other things. It's higly recommended
|
||||
* that you load this script into your dialogs.
|
||||
*
|
||||
* @static
|
||||
* @member tinyMCEPopup
|
||||
* @class tinyMCEPopup
|
||||
*/
|
||||
tinyMCEPopup = {
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initializes the popup this will be called automatically.
|
||||
*
|
||||
* @method init
|
||||
*/
|
||||
init : function() {
|
||||
var t = this, w, ti, li, q, i, it;
|
||||
|
||||
li = ('' + document.location.search).replace(/^\?/, '').split('&');
|
||||
q = {};
|
||||
for (i=0; i<li.length; i++) {
|
||||
it = li[i].split('=');
|
||||
q[unescape(it[0])] = unescape(it[1]);
|
||||
}
|
||||
|
||||
if (q.mce_rdomain)
|
||||
document.domain = q.mce_rdomain;
|
||||
var t = this, w, ti;
|
||||
|
||||
// Find window & API
|
||||
w = t.getWin();
|
||||
@@ -68,15 +56,18 @@ tinyMCEPopup = {
|
||||
/**
|
||||
* Returns the reference to the parent window that opened the dialog.
|
||||
*
|
||||
* @method getWin
|
||||
* @return {Window} Reference to the parent window that opened the dialog.
|
||||
*/
|
||||
getWin : function() {
|
||||
return window.dialogArguments || opener || parent || top;
|
||||
// Added frameElement check to fix bug: #2817583
|
||||
return (!window.frameElement && window.dialogArguments) || opener || parent || top;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a window argument/parameter by name.
|
||||
*
|
||||
* @method getWindowArg
|
||||
* @param {String} n Name of the window argument to retrive.
|
||||
* @param {String} dv Optional default value to return.
|
||||
* @return {String} Argument value or default value if it wasn't found.
|
||||
@@ -90,6 +81,7 @@ tinyMCEPopup = {
|
||||
/**
|
||||
* Returns a editor parameter/config option value.
|
||||
*
|
||||
* @method getParam
|
||||
* @param {String} n Name of the editor config option to retrive.
|
||||
* @param {String} dv Optional default value to return.
|
||||
* @return {String} Parameter value or default value if it wasn't found.
|
||||
@@ -101,6 +93,7 @@ tinyMCEPopup = {
|
||||
/**
|
||||
* Returns a language item by key.
|
||||
*
|
||||
* @method getLang
|
||||
* @param {String} n Language item like mydialog.something.
|
||||
* @param {String} dv Optional default value to return.
|
||||
* @return {String} Language value for the item like "my string" or the default value if it wasn't found.
|
||||
@@ -112,8 +105,9 @@ tinyMCEPopup = {
|
||||
/**
|
||||
* Executed a command on editor that opened the dialog/popup.
|
||||
*
|
||||
* @method execCommand
|
||||
* @param {String} cmd Command to execute.
|
||||
* @param {bool} ui Optional boolean value if the UI for the command should be presented or not.
|
||||
* @param {Boolean} ui Optional boolean value if the UI for the command should be presented or not.
|
||||
* @param {Object} val Optional value to pass with the comman like an URL.
|
||||
* @param {Object} a Optional arguments object.
|
||||
*/
|
||||
@@ -128,6 +122,8 @@ tinyMCEPopup = {
|
||||
/**
|
||||
* Resizes the dialog to the inner size of the window. This is needed since various browsers
|
||||
* have different border sizes on windows.
|
||||
*
|
||||
* @method resizeToInnerSize
|
||||
*/
|
||||
resizeToInnerSize : function() {
|
||||
var t = this, n, b = document.body, vp = t.dom.getViewPort(window), dw, dh;
|
||||
@@ -145,6 +141,7 @@ tinyMCEPopup = {
|
||||
* Will executed the specified string when the page has been loaded. This function
|
||||
* was added for compatibility with the 2.x branch.
|
||||
*
|
||||
* @method executeOnLoad
|
||||
* @param {String} s String to evalutate on init.
|
||||
*/
|
||||
executeOnLoad : function(s) {
|
||||
@@ -156,14 +153,18 @@ tinyMCEPopup = {
|
||||
/**
|
||||
* Stores the current editor selection for later restoration. This can be useful since some browsers
|
||||
* looses it's selection if a control element is selected/focused inside the dialogs.
|
||||
*
|
||||
* @method storeSelection
|
||||
*/
|
||||
storeSelection : function() {
|
||||
this.editor.windowManager.bookmark = tinyMCEPopup.editor.selection.getBookmark('simple');
|
||||
this.editor.windowManager.bookmark = tinyMCEPopup.editor.selection.getBookmark(1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Restores any stored selection. This can be useful since some browsers
|
||||
* looses it's selection if a control element is selected/focused inside the dialogs.
|
||||
*
|
||||
* @method restoreSelection
|
||||
*/
|
||||
restoreSelection : function() {
|
||||
var t = tinyMCEPopup;
|
||||
@@ -175,12 +176,14 @@ tinyMCEPopup = {
|
||||
/**
|
||||
* Loads a specific dialog language pack. If you pass in plugin_url as a arugment
|
||||
* when you open the window it will load the <plugin url>/langs/<code>_dlg.js lang pack file.
|
||||
*
|
||||
* @method requireLangPack
|
||||
*/
|
||||
requireLangPack : function() {
|
||||
var u = this.getWindowArg('plugin_url') || this.getWindowArg('theme_url');
|
||||
var t = this, u = t.getWindowArg('plugin_url') || t.getWindowArg('theme_url');
|
||||
|
||||
if (u && this.editor.settings.language) {
|
||||
u += '/langs/' + this.editor.settings.language + '_dlg.js';
|
||||
if (u && t.editor.settings.language && t.features.translate_i18n !== false) {
|
||||
u += '/langs/' + t.editor.settings.language + '_dlg.js';
|
||||
|
||||
if (!tinymce.ScriptLoader.isDone(u)) {
|
||||
document.write('<script type="text/javascript" src="' + tinymce._addVer(u) + '"></script>');
|
||||
@@ -193,6 +196,7 @@ tinyMCEPopup = {
|
||||
* Executes a color picker on the specified element id. When the user
|
||||
* then selects a color it will be set as the value of the specified element.
|
||||
*
|
||||
* @method pickColor
|
||||
* @param {DOMEvent} e DOM event object.
|
||||
* @param {string} element_id Element id to be filled with the color value from the picker.
|
||||
*/
|
||||
@@ -215,6 +219,7 @@ tinyMCEPopup = {
|
||||
* Opens a filebrowser/imagebrowser this will set the output value from
|
||||
* the browser as a value on the specified element.
|
||||
*
|
||||
* @method openBrowser
|
||||
* @param {string} element_id Id of the element to set value in.
|
||||
* @param {string} type Type of browser to open image/file/flash.
|
||||
* @param {string} option Option name to get the file_broswer_callback function name from.
|
||||
@@ -228,6 +233,7 @@ tinyMCEPopup = {
|
||||
* Creates a confirm dialog. Please don't use the blocking behavior of this
|
||||
* native version use the callback method instead then it can be extended.
|
||||
*
|
||||
* @method confirm
|
||||
* @param {String} t Title for the new confirm dialog.
|
||||
* @param {function} cb Callback function to be executed after the user has selected ok or cancel.
|
||||
* @param {Object} s Optional scope to execute the callback in.
|
||||
@@ -240,6 +246,7 @@ tinyMCEPopup = {
|
||||
* Creates a alert dialog. Please don't use the blocking behavior of this
|
||||
* native version use the callback method instead then it can be extended.
|
||||
*
|
||||
* @method alert
|
||||
* @param {String} t Title for the new alert dialog.
|
||||
* @param {function} cb Callback function to be executed after the user has selected ok.
|
||||
* @param {Object} s Optional scope to execute the callback in.
|
||||
@@ -250,6 +257,8 @@ tinyMCEPopup = {
|
||||
|
||||
/**
|
||||
* Closes the current window.
|
||||
*
|
||||
* @method close
|
||||
*/
|
||||
close : function() {
|
||||
var t = this;
|
||||
@@ -284,7 +293,12 @@ tinyMCEPopup = {
|
||||
},*/
|
||||
|
||||
_onDOMLoaded : function() {
|
||||
var t = this, ti = document.title, bm, h, nv;
|
||||
var t = tinyMCEPopup, ti = document.title, bm, h, nv;
|
||||
|
||||
if (t.domLoaded)
|
||||
return;
|
||||
|
||||
t.domLoaded = 1;
|
||||
|
||||
// Translate page
|
||||
if (t.features.translate_i18n !== false) {
|
||||
@@ -306,9 +320,13 @@ tinyMCEPopup = {
|
||||
document.body.style.display = '';
|
||||
|
||||
// Restore selection in IE when focus is placed on a non textarea or input element of the type text
|
||||
if (tinymce.isIE)
|
||||
if (tinymce.isIE) {
|
||||
document.attachEvent('onmouseup', tinyMCEPopup._restoreSelection);
|
||||
|
||||
// Add base target element for it since it would fail with modal dialogs
|
||||
t.dom.add(t.dom.select('head')[0], 'base', {target : '_self'});
|
||||
}
|
||||
|
||||
t.restoreSelection();
|
||||
t.resizeToInnerSize();
|
||||
|
||||
@@ -374,30 +392,37 @@ tinyMCEPopup = {
|
||||
},
|
||||
|
||||
_wait : function() {
|
||||
var t = this, ti;
|
||||
|
||||
if (tinymce.isIE && document.location.protocol != 'https:') {
|
||||
// Fake DOMContentLoaded on IE
|
||||
document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>');
|
||||
document.getElementById("__ie_onload").onreadystatechange = function() {
|
||||
if (this.readyState == "complete") {
|
||||
t._onDOMLoaded();
|
||||
document.getElementById("__ie_onload").onreadystatechange = null; // Prevent leak
|
||||
// Use IE method
|
||||
if (document.attachEvent) {
|
||||
document.attachEvent("onreadystatechange", function() {
|
||||
if (document.readyState === "complete") {
|
||||
document.detachEvent("onreadystatechange", arguments.callee);
|
||||
tinyMCEPopup._onDOMLoaded();
|
||||
}
|
||||
};
|
||||
} else {
|
||||
if (tinymce.isIE || tinymce.isWebKit) {
|
||||
ti = setInterval(function() {
|
||||
if (/loaded|complete/.test(document.readyState)) {
|
||||
clearInterval(ti);
|
||||
t._onDOMLoaded();
|
||||
});
|
||||
|
||||
if (document.documentElement.doScroll && window == window.top) {
|
||||
(function() {
|
||||
if (tinyMCEPopup.domLoaded)
|
||||
return;
|
||||
|
||||
try {
|
||||
// If IE is used, use the trick by Diego Perini
|
||||
// http://javascript.nwbox.com/IEContentLoaded/
|
||||
document.documentElement.doScroll("left");
|
||||
} catch (ex) {
|
||||
setTimeout(arguments.callee, 0);
|
||||
return;
|
||||
}
|
||||
}, 10);
|
||||
} else {
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
t._onDOMLoaded();
|
||||
}, false);
|
||||
|
||||
tinyMCEPopup._onDOMLoaded();
|
||||
})();
|
||||
}
|
||||
|
||||
document.attachEvent('onload', tinyMCEPopup._onDOMLoaded);
|
||||
} else if (document.addEventListener) {
|
||||
window.addEventListener('DOMContentLoaded', tinyMCEPopup._onDOMLoaded, false);
|
||||
window.addEventListener('load', tinyMCEPopup._onDOMLoaded, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
+153
-149
@@ -1,181 +1,185 @@
|
||||
/**
|
||||
* $Id: UndoManager.js 828 2008-04-29 16:02:54Z spocke $
|
||||
* $Id: UndoManager.js 1190 2009-08-12 17:59:29Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* @class This class handles the undo/redo history levels for the editor. Since the build in undo/redo has major drawbacks a custom one was needed.
|
||||
* @member tinymce.UndoManager
|
||||
*/
|
||||
tinymce.create('tinymce.UndoManager', {
|
||||
index : 0,
|
||||
data : null,
|
||||
typing : 0,
|
||||
|
||||
(function(tinymce) {
|
||||
/**
|
||||
* Constructs a new UndoManager instance.
|
||||
*
|
||||
* @constructor
|
||||
* @param {tinymce.Editor} ed Editor instance to undo/redo in.
|
||||
* This class handles the undo/redo history levels for the editor. Since the build in undo/redo has major drawbacks a custom one was needed.
|
||||
* @class tinymce.UndoManager
|
||||
*/
|
||||
UndoManager : function(ed) {
|
||||
var t = this, Dispatcher = tinymce.util.Dispatcher;
|
||||
tinymce.create('tinymce.UndoManager', {
|
||||
index : 0,
|
||||
data : null,
|
||||
typing : 0,
|
||||
|
||||
t.editor = ed;
|
||||
t.data = [];
|
||||
t.onAdd = new Dispatcher(this);
|
||||
t.onUndo = new Dispatcher(this);
|
||||
t.onRedo = new Dispatcher(this);
|
||||
},
|
||||
/**
|
||||
* Constructs a new UndoManager instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method UndoManager
|
||||
* @param {tinymce.Editor} ed Editor instance to undo/redo in.
|
||||
*/
|
||||
UndoManager : function(ed) {
|
||||
var t = this, Dispatcher = tinymce.util.Dispatcher;
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
t.editor = ed;
|
||||
t.data = [];
|
||||
t.onAdd = new Dispatcher(this);
|
||||
t.onUndo = new Dispatcher(this);
|
||||
t.onRedo = new Dispatcher(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a new undo level/snapshot to the undo list.
|
||||
*
|
||||
* @param {Object} l Optional undo level object to add.
|
||||
* @return {Object} Undo level that got added or null it a level wasn't needed.
|
||||
*/
|
||||
add : function(l) {
|
||||
var t = this, i, ed = t.editor, b, s = ed.settings, la;
|
||||
/**
|
||||
* Adds a new undo level/snapshot to the undo list.
|
||||
*
|
||||
* @method add
|
||||
* @param {Object} l Optional undo level object to add.
|
||||
* @return {Object} Undo level that got added or null it a level wasn't needed.
|
||||
*/
|
||||
add : function(l) {
|
||||
var t = this, i, ed = t.editor, b, s = ed.settings, la;
|
||||
|
||||
l = l || {};
|
||||
l.content = l.content || ed.getContent({format : 'raw', no_events : 1});
|
||||
l = l || {};
|
||||
l.content = l.content || ed.getContent({format : 'raw', no_events : 1});
|
||||
|
||||
// Add undo level if needed
|
||||
l.content = l.content.replace(/^\s*|\s*$/g, '');
|
||||
la = t.data[t.index > 0 && (t.index == 0 || t.index == t.data.length) ? t.index - 1 : t.index];
|
||||
if (!l.initial && la && l.content == la.content)
|
||||
return null;
|
||||
// Add undo level if needed
|
||||
l.content = l.content.replace(/^\s*|\s*$/g, '');
|
||||
la = t.data[t.index > 0 && (t.index == 0 || t.index == t.data.length) ? t.index - 1 : t.index];
|
||||
if (!l.initial && la && l.content == la.content)
|
||||
return null;
|
||||
|
||||
// Time to compress
|
||||
if (s.custom_undo_redo_levels) {
|
||||
if (t.data.length > s.custom_undo_redo_levels) {
|
||||
for (i = 0; i < t.data.length - 1; i++)
|
||||
t.data[i] = t.data[i + 1];
|
||||
// Time to compress
|
||||
if (s.custom_undo_redo_levels) {
|
||||
if (t.data.length > s.custom_undo_redo_levels) {
|
||||
for (i = 0; i < t.data.length - 1; i++)
|
||||
t.data[i] = t.data[i + 1];
|
||||
|
||||
t.data.length--;
|
||||
t.index = t.data.length;
|
||||
t.data.length--;
|
||||
t.index = t.data.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (s.custom_undo_redo_restore_selection && !l.initial)
|
||||
l.bookmark = b = l.bookmark || ed.selection.getBookmark();
|
||||
if (s.custom_undo_redo_restore_selection && !l.initial)
|
||||
l.bookmark = b = l.bookmark || ed.selection.getBookmark();
|
||||
|
||||
if (t.index < t.data.length)
|
||||
t.index++;
|
||||
if (t.index < t.data.length)
|
||||
t.index++;
|
||||
|
||||
// Only initial marked undo levels should be allowed as first item
|
||||
// This to workaround a bug with Firefox and the blur event
|
||||
if (t.data.length === 0 && !l.initial)
|
||||
return null;
|
||||
// Only initial marked undo levels should be allowed as first item
|
||||
// This to workaround a bug with Firefox and the blur event
|
||||
if (t.data.length === 0 && !l.initial)
|
||||
return null;
|
||||
|
||||
// Add level
|
||||
t.data.length = t.index + 1;
|
||||
t.data[t.index++] = l;
|
||||
// Add level
|
||||
t.data.length = t.index + 1;
|
||||
t.data[t.index++] = l;
|
||||
|
||||
if (l.initial)
|
||||
t.index = 0;
|
||||
if (l.initial)
|
||||
t.index = 0;
|
||||
|
||||
// Set initial bookmark use first real undo level
|
||||
if (t.data.length == 2 && t.data[0].initial)
|
||||
t.data[0].bookmark = b;
|
||||
// Set initial bookmark use first real undo level
|
||||
if (t.data.length == 2 && t.data[0].initial)
|
||||
t.data[0].bookmark = b;
|
||||
|
||||
t.onAdd.dispatch(t, l);
|
||||
ed.isNotDirty = 0;
|
||||
t.onAdd.dispatch(t, l);
|
||||
ed.isNotDirty = 0;
|
||||
|
||||
//console.dir(t.data);
|
||||
//console.dir(t.data);
|
||||
|
||||
return l;
|
||||
},
|
||||
return l;
|
||||
},
|
||||
|
||||
/**
|
||||
* Undoes the last action.
|
||||
*
|
||||
* @return {Object} Undo level or null if no undo was performed.
|
||||
*/
|
||||
undo : function() {
|
||||
var t = this, ed = t.editor, l = l, i;
|
||||
/**
|
||||
* Undoes the last action.
|
||||
*
|
||||
* @method undo
|
||||
* @return {Object} Undo level or null if no undo was performed.
|
||||
*/
|
||||
undo : function() {
|
||||
var t = this, ed = t.editor, l = l, i;
|
||||
|
||||
if (t.typing) {
|
||||
t.add();
|
||||
t.typing = 0;
|
||||
}
|
||||
|
||||
if (t.index > 0) {
|
||||
// If undo on last index then take snapshot
|
||||
if (t.index == t.data.length && t.index > 1) {
|
||||
i = t.index;
|
||||
if (t.typing) {
|
||||
t.add();
|
||||
t.typing = 0;
|
||||
|
||||
if (!t.add())
|
||||
t.index = i;
|
||||
|
||||
--t.index;
|
||||
}
|
||||
|
||||
l = t.data[--t.index];
|
||||
ed.setContent(l.content, {format : 'raw'});
|
||||
ed.selection.moveToBookmark(l.bookmark);
|
||||
if (t.index > 0) {
|
||||
// If undo on last index then take snapshot
|
||||
if (t.index == t.data.length && t.index > 1) {
|
||||
i = t.index;
|
||||
t.typing = 0;
|
||||
|
||||
t.onUndo.dispatch(t, l);
|
||||
if (!t.add())
|
||||
t.index = i;
|
||||
|
||||
--t.index;
|
||||
}
|
||||
|
||||
l = t.data[--t.index];
|
||||
ed.setContent(l.content, {format : 'raw'});
|
||||
ed.selection.moveToBookmark(l.bookmark);
|
||||
|
||||
t.onUndo.dispatch(t, l);
|
||||
}
|
||||
|
||||
return l;
|
||||
},
|
||||
|
||||
/**
|
||||
* Redoes the last action.
|
||||
*
|
||||
* @method redo
|
||||
* @return {Object} Redo level or null if no redo was performed.
|
||||
*/
|
||||
redo : function() {
|
||||
var t = this, ed = t.editor, l = null;
|
||||
|
||||
if (t.index < t.data.length - 1) {
|
||||
l = t.data[++t.index];
|
||||
ed.setContent(l.content, {format : 'raw'});
|
||||
ed.selection.moveToBookmark(l.bookmark);
|
||||
|
||||
t.onRedo.dispatch(t, l);
|
||||
}
|
||||
|
||||
return l;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes all undo levels.
|
||||
*
|
||||
* @method clear
|
||||
*/
|
||||
clear : function() {
|
||||
var t = this;
|
||||
|
||||
t.data = [];
|
||||
t.index = 0;
|
||||
t.typing = 0;
|
||||
t.add({initial : true});
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true/false if the undo manager has any undo levels.
|
||||
*
|
||||
* @method hasUndo
|
||||
* @return {Boolean} true/false if the undo manager has any undo levels.
|
||||
*/
|
||||
hasUndo : function() {
|
||||
return this.index != 0 || this.typing;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true/false if the undo manager has any redo levels.
|
||||
*
|
||||
* @method hasRedo
|
||||
* @return {Boolean} true/false if the undo manager has any redo levels.
|
||||
*/
|
||||
hasRedo : function() {
|
||||
return this.index < this.data.length - 1;
|
||||
}
|
||||
|
||||
return l;
|
||||
},
|
||||
|
||||
/**
|
||||
* Redoes the last action.
|
||||
*
|
||||
* @return {Object} Redo level or null if no redo was performed.
|
||||
*/
|
||||
redo : function() {
|
||||
var t = this, ed = t.editor, l = null;
|
||||
|
||||
if (t.index < t.data.length - 1) {
|
||||
l = t.data[++t.index];
|
||||
ed.setContent(l.content, {format : 'raw'});
|
||||
ed.selection.moveToBookmark(l.bookmark);
|
||||
|
||||
t.onRedo.dispatch(t, l);
|
||||
}
|
||||
|
||||
return l;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes all undo levels.
|
||||
*/
|
||||
clear : function() {
|
||||
var t = this;
|
||||
|
||||
t.data = [];
|
||||
t.index = 0;
|
||||
t.typing = 0;
|
||||
t.add({initial : true});
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true/false if the undo manager has any undo levels.
|
||||
*
|
||||
* @return {bool} true/false if the undo manager has any undo levels.
|
||||
*/
|
||||
hasUndo : function() {
|
||||
return this.index != 0 || this.typing;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true/false if the undo manager has any redo levels.
|
||||
*
|
||||
* @return {bool} true/false if the undo manager has any redo levels.
|
||||
*/
|
||||
hasRedo : function() {
|
||||
return this.index < this.data.length - 1;
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
});
|
||||
})(tinymce);
|
||||
|
||||
+12
-15
@@ -1,22 +1,23 @@
|
||||
/**
|
||||
* $Id: WindowManager.js 890 2008-07-09 10:40:52Z spocke $
|
||||
* $Id: WindowManager.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isIE = tinymce.isIE, isOpera = tinymce.isOpera;
|
||||
|
||||
/**#@+
|
||||
* @class This class handles the creation of native windows and dialogs. This class can be extended to provide for example inline dialogs.
|
||||
* @member tinymce.WindowManager
|
||||
/**
|
||||
* This class handles the creation of native windows and dialogs. This class can be extended to provide for example inline dialogs.
|
||||
* @class tinymce.WindowManager
|
||||
*/
|
||||
tinymce.create('tinymce.WindowManager', {
|
||||
/**
|
||||
* Constructs a new window manager instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method WindowManager
|
||||
* @param {tinymce.Editor} ed Editor instance that the windows are bound to.
|
||||
*/
|
||||
WindowManager : function(ed) {
|
||||
@@ -29,13 +30,10 @@
|
||||
t.features = {};
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Opens a new window.
|
||||
*
|
||||
* @method open
|
||||
* @param {Object} s Optional name/value settings collection contains things like width/height/url etc.
|
||||
* @param {Object} p Optional parameters/arguments collection can be used by the dialogs to retrive custom parameters.
|
||||
*/
|
||||
@@ -86,9 +84,6 @@
|
||||
t.onOpen.dispatch(t, s, p);
|
||||
|
||||
u = s.url || s.file;
|
||||
if (tinymce.relaxedDomain)
|
||||
u += (u.indexOf('?') == -1 ? '?' : '&') + 'mce_rdomain=' + tinymce.relaxedDomain;
|
||||
|
||||
u = tinymce._addVer(u);
|
||||
|
||||
try {
|
||||
@@ -108,6 +103,7 @@
|
||||
/**
|
||||
* Closes the specified window. This will also dispatch out a onClose event.
|
||||
*
|
||||
* @method close
|
||||
* @param {Window} w Native window object to close.
|
||||
*/
|
||||
close : function(w) {
|
||||
@@ -120,6 +116,7 @@
|
||||
* of classes from a parent window due to some reference problem. Any arguments passed after the class name
|
||||
* will be passed as arguments to the constructor.
|
||||
*
|
||||
* @method createInstance
|
||||
* @param {String} cl Class name to create an instance of.
|
||||
* @return {Object} Instance of the specified class.
|
||||
*/
|
||||
@@ -133,6 +130,7 @@
|
||||
* Creates a confirm dialog. Please don't use the blocking behavior of this
|
||||
* native version use the callback method instead then it can be extended.
|
||||
*
|
||||
* @method confirm
|
||||
* @param {String} t Title for the new confirm dialog.
|
||||
* @param {function} cb Callback function to be executed after the user has selected ok or cancel.
|
||||
* @param {Object} s Optional scope to execute the callback in.
|
||||
@@ -147,6 +145,7 @@
|
||||
* Creates a alert dialog. Please don't use the blocking behavior of this
|
||||
* native version use the callback method instead then it can be extended.
|
||||
*
|
||||
* @method alert
|
||||
* @param {String} t Title for the new alert dialog.
|
||||
* @param {function} cb Callback function to be executed after the user has selected ok.
|
||||
* @param {Object} s Optional scope to execute the callback in.
|
||||
@@ -166,7 +165,5 @@
|
||||
_decode : function(s) {
|
||||
return tinymce.DOM.decode(s).replace(/\\n/g, '\n');
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
}());
|
||||
}(tinymce));
|
||||
+84
-54
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: adapter.js 520 2008-01-07 16:30:32Z spocke $
|
||||
* $Id: adapter.js 1200 2009-08-18 12:32:02Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
@@ -7,9 +7,9 @@
|
||||
* This file contains all adapter logic needed to use jQuery as the base API for TinyMCE.
|
||||
*/
|
||||
|
||||
// #if jquery_adapter
|
||||
// #ifdef jquery_adapter
|
||||
|
||||
(function($) {
|
||||
(function($, tinymce) {
|
||||
var is = tinymce.is;
|
||||
|
||||
if (!window.jQuery)
|
||||
@@ -18,99 +18,135 @@
|
||||
// Patch in core NS functions
|
||||
tinymce.extend = $.extend;
|
||||
tinymce.extend(tinymce, {
|
||||
trim : $.trim,
|
||||
map : $.map,
|
||||
grep : function(a, f) {return $.grep(a, f || function(){return 1;});},
|
||||
inArray : function(a, v) {return $.inArray(v, a || []);},
|
||||
each: function(o, cb, s) {
|
||||
if (!o) return 0;
|
||||
inArray : function(a, v) {return $.inArray(v, a || []);}
|
||||
|
||||
/* Didn't iterate stylesheets
|
||||
each : function(o, cb, s) {
|
||||
if (!o)
|
||||
return 0;
|
||||
|
||||
var r = 1;
|
||||
|
||||
$.each(o, function(nr, el){
|
||||
if (cb.call(s, el, nr, o) === false) {
|
||||
r = 0;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return r;
|
||||
}
|
||||
}*/
|
||||
});
|
||||
|
||||
// Patch in functions in various clases
|
||||
// Add a "#if !jquery" statement around each core API function you add below
|
||||
// Add a "#ifndefjquery" statement around each core API function you add below
|
||||
var patches = {
|
||||
'tinymce.dom.DOMUtils' : {
|
||||
addClass: function(e, c) {
|
||||
/*
|
||||
addClass : function(e, c) {
|
||||
if (is(e, 'array') && is(e[0], 'string'))
|
||||
e = e.join(',#');
|
||||
return (e && $(is(e, 'string') ? '#' + e : e)
|
||||
.addClass(c)
|
||||
.attr('class')) || false;
|
||||
},
|
||||
|
||||
hasClass : function(n, c) {
|
||||
return $(is(n, 'string') ? '#' + n : n).hasClass(c);
|
||||
},
|
||||
removeClass: function(e, c) {
|
||||
|
||||
removeClass : function(e, c) {
|
||||
if (!e)
|
||||
return false;
|
||||
|
||||
var r = [];
|
||||
|
||||
$(is(e, 'string') ? '#' + e : e)
|
||||
.removeClass(c)
|
||||
.each(function(){
|
||||
r.push(this.className);
|
||||
});
|
||||
|
||||
return r.length == 1 ? r[0] : r;
|
||||
},
|
||||
select : function(p, c) {
|
||||
return tinymce.grep($(p, this.get(c) || this.doc));
|
||||
*/
|
||||
|
||||
select : function(pattern, scope) {
|
||||
var t = this;
|
||||
|
||||
return $.find(pattern, t.get(scope) || t.get(t.settings.root_element) || t.doc, []);
|
||||
},
|
||||
show: function(e) {
|
||||
|
||||
is : function(n, patt) {
|
||||
return $(this.get(n)).is(patt);
|
||||
}
|
||||
|
||||
/*
|
||||
show : function(e) {
|
||||
if (is(e, 'array') && is(e[0], 'string'))
|
||||
e = e.join(',#');
|
||||
$(is(e, 'string') ? '#' + e : e).css('display','block');
|
||||
|
||||
$(is(e, 'string') ? '#' + e : e).css('display', 'block');
|
||||
},
|
||||
hide: function(e) {
|
||||
|
||||
hide : function(e) {
|
||||
if (is(e, 'array') && is(e[0], 'string'))
|
||||
e = e.join(',#');
|
||||
$(is(e, 'string') ? '#' + e : e).css('display','none');
|
||||
|
||||
$(is(e, 'string') ? '#' + e : e).css('display', 'none');
|
||||
},
|
||||
isHidden: function(e) {
|
||||
|
||||
isHidden : function(e) {
|
||||
return $(is(e, 'string') ? '#' + e : e).is(':hidden');
|
||||
},
|
||||
insertAfter: function(n,e) {
|
||||
|
||||
insertAfter : function(n, e) {
|
||||
return $(is(e, 'string') ? '#' + e : e).after(n);
|
||||
},
|
||||
replace: function(o, n, k) {
|
||||
|
||||
replace : function(o, n, k) {
|
||||
n = $(is(n, 'string') ? '#' + n : n);
|
||||
if (k) {
|
||||
|
||||
if (k)
|
||||
n.children().appendTo(o);
|
||||
}
|
||||
|
||||
n.replaceWith(o);
|
||||
},
|
||||
setStyle: function(n, na, v) {
|
||||
|
||||
setStyle : function(n, na, v) {
|
||||
if (is(n, 'array') && is(n[0], 'string'))
|
||||
n = n.join(',#');
|
||||
|
||||
$(is(n, 'string') ? '#' + n : n).css(na, v);
|
||||
},
|
||||
getStyle: function(n, na, c) {
|
||||
|
||||
getStyle : function(n, na, c) {
|
||||
return $(is(n, 'string') ? '#' + n : n).css(na);
|
||||
},
|
||||
setStyles: function(e, o) {
|
||||
|
||||
setStyles : function(e, o) {
|
||||
if (is(e, 'array') && is(e[0], 'string'))
|
||||
e = e.join(',#');
|
||||
$(is(e, 'string') ? '#' + e : e).css(o);
|
||||
},
|
||||
|
||||
setAttrib : function(e, n, v) {
|
||||
var t = this;
|
||||
var s = t.settings;
|
||||
var t = this, s = t.settings;
|
||||
|
||||
if (is(e, 'array') && is(e[0], 'string'))
|
||||
e = e.join(',#');
|
||||
|
||||
e = $(is(e, 'string') ? '#' + e : e);
|
||||
|
||||
switch (n) {
|
||||
case "style":
|
||||
e.each(function(){
|
||||
e.each(function(i, v){
|
||||
if (s.keep_values)
|
||||
$(this).attr('mce_style', v);
|
||||
this.style.cssText = v;
|
||||
$(v).attr('mce_style', v);
|
||||
|
||||
v.style.cssText = v;
|
||||
});
|
||||
break;
|
||||
|
||||
@@ -122,12 +158,12 @@
|
||||
|
||||
case "src":
|
||||
case "href":
|
||||
e.each(function(){
|
||||
e.each(function(i, v){
|
||||
if (s.keep_values) {
|
||||
if (s.url_converter)
|
||||
v = s.url_converter.call(s.url_converter_scope || t, v, n, this);
|
||||
|
||||
t.setAttrib(this, 'mce_' + n, v);
|
||||
v = s.url_converter.call(s.url_converter_scope || t, v, n, v);
|
||||
|
||||
t.setAttrib(v, 'mce_' + n, v);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -139,29 +175,22 @@
|
||||
else
|
||||
e.removeAttr(n);
|
||||
},
|
||||
setAttribs: function(e, o) {
|
||||
|
||||
setAttribs : function(e, o) {
|
||||
var t = this;
|
||||
|
||||
$.each(o, function(n, v){
|
||||
t.setAttrib(e,n,v);
|
||||
});
|
||||
}
|
||||
/*run: function(e, f, s) {
|
||||
if (!e)
|
||||
return false;
|
||||
var r = [];
|
||||
if (is(e, 'array') && is(e[0], 'string'))
|
||||
e = e.join(',#');
|
||||
$(is(e, 'string') ? '#' + e : e)
|
||||
.each(function(i, e){
|
||||
r.push(f.call(s, e, i));
|
||||
});
|
||||
return r.length == 0 ? f.call(s, e) : r;
|
||||
}*/
|
||||
},
|
||||
'tinymce.dom.Event': {
|
||||
add: function (o, n, f, s) {
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
'tinymce.dom.Event' : {
|
||||
add : function (o, n, f, s) {
|
||||
var lo, cb;
|
||||
|
||||
|
||||
cb = function(e) {
|
||||
e.target = e.target || this;
|
||||
f.call(s || this, e);
|
||||
@@ -186,7 +215,7 @@
|
||||
return cb;
|
||||
},
|
||||
|
||||
remove: function(o, n, f) {
|
||||
remove : function(o, n, f) {
|
||||
// Find cfunc
|
||||
$(this._jqLookup).each(function() {
|
||||
if (this.func === f)
|
||||
@@ -195,18 +224,19 @@
|
||||
|
||||
if (is(o, 'array') && is(o[0], 'string'))
|
||||
o = o.join(',#');
|
||||
|
||||
|
||||
$(is(o, 'string') ? '#' + o : o).unbind(n,f);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
// Patch functions after a class is created
|
||||
tinymce.onCreate = function(ty, c, p) {
|
||||
tinymce.extend(p, patches[c]);
|
||||
};
|
||||
})(jQuery);
|
||||
})(jQuery, tinymce);
|
||||
|
||||
// #endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* $Id: jquery.uri.js 453 2008-10-14 12:24:41Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
var lazyLoading, delayedInits = [];
|
||||
|
||||
function patch(type, name, patch_func) {
|
||||
var func;
|
||||
|
||||
func = $.fn[name];
|
||||
|
||||
$.fn[name] = function() {
|
||||
var val;
|
||||
|
||||
if (type !== 'after') {
|
||||
val = patch_func.apply(this, arguments);
|
||||
|
||||
// We got a return value pass out that instead
|
||||
if (val !== undefined)
|
||||
return val;
|
||||
}
|
||||
|
||||
val = func.apply(this, arguments);
|
||||
|
||||
if (type !== 'before')
|
||||
patch_func.apply(this, arguments);
|
||||
|
||||
return val;
|
||||
};
|
||||
};
|
||||
|
||||
$.fn.tinymce = function(settings) {
|
||||
var t = this, url, suffix = '', ed;
|
||||
|
||||
// No match then just ignore the call
|
||||
if (!t.length)
|
||||
return;
|
||||
|
||||
// Get editor instance
|
||||
if (!settings)
|
||||
return tinyMCE.get(this[0].id);
|
||||
|
||||
function init() {
|
||||
// Apply patches once
|
||||
if (applyPatch) {
|
||||
applyPatch();
|
||||
applyPatch = null;
|
||||
}
|
||||
|
||||
// Create an editor instance for each matched node
|
||||
t.each(function(i, n) {
|
||||
var ed, id = n.id || tinymce.DOM.uniqueId();
|
||||
|
||||
n.id = id;
|
||||
ed = new tinymce.Editor(id, settings);
|
||||
|
||||
ed.render();
|
||||
});
|
||||
};
|
||||
|
||||
// Load TinyMCE on demand
|
||||
if (!window['tinymce'] && !lazyLoading && (url = settings.script_url)) {
|
||||
lazyLoading = 1;
|
||||
|
||||
if (/_(src|dev)\.js/g.test(url))
|
||||
suffix = '_src';
|
||||
|
||||
window.tinyMCEPreInit = {
|
||||
base : url.substring(0, url.lastIndexOf('/')),
|
||||
suffix : suffix,
|
||||
query : ''
|
||||
};
|
||||
|
||||
$.getScript(url, function() {
|
||||
// Script is loaded time to initialize TinyMCE
|
||||
tinymce.dom.Event.domLoaded = 1;
|
||||
lazyLoading = 2;
|
||||
init();
|
||||
|
||||
$.each(delayedInits, function(i, init) {
|
||||
init();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
if (lazyLoading === 1)
|
||||
delayedInits.push(init);
|
||||
else
|
||||
init();
|
||||
}
|
||||
};
|
||||
|
||||
// Add :tinymce psuedo selector
|
||||
$.extend($.expr[':'], {
|
||||
tinymce : function(e) {
|
||||
return e.id && !!tinyMCE.get(e.id);
|
||||
}
|
||||
});
|
||||
|
||||
function applyPatch() {
|
||||
function removeEditors() {
|
||||
this.find('span.mceEditor,div.mceEditor').each(function(i, n) {
|
||||
var ed;
|
||||
|
||||
if (ed = tinyMCE.get(n.id.replace(/_parent$/, ''))) {
|
||||
ed.remove();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function loadOrSave(value) {
|
||||
var ed;
|
||||
|
||||
// Handle set value
|
||||
if (value !== undefined) {
|
||||
removeEditors.call(this);
|
||||
|
||||
// Saves the contents before get/set value of textarea/div
|
||||
this.each(function(i, node) {
|
||||
var ed;
|
||||
|
||||
if (ed = tinyMCE.get(node.id))
|
||||
ed.setContent(value);
|
||||
});
|
||||
} else if (this.length > 0) {
|
||||
// Handle get value
|
||||
if (ed = tinyMCE.get(this[0].id))
|
||||
return ed.getContent();
|
||||
}
|
||||
};
|
||||
|
||||
// Patch various jQuery functions
|
||||
patch("both", 'text', function(value) {
|
||||
// Text encode value
|
||||
if (value !== undefined)
|
||||
return loadOrSave.call(this, value);
|
||||
|
||||
// Get contents as plain text
|
||||
if (this.length > 0) {
|
||||
// Handle get value
|
||||
if (ed = tinyMCE.get(this[0].id))
|
||||
return ed.getContent().replace(/<[^>]+>/g, '');
|
||||
}
|
||||
});
|
||||
|
||||
$.each(['val', 'html'], function(i, name) {
|
||||
patch("both", name, loadOrSave);
|
||||
});
|
||||
|
||||
$.each(['append', 'prepend'], function(i, name) {
|
||||
patch("before", name, function(value) {
|
||||
if (value !== undefined) {
|
||||
this.each(function(i, node) {
|
||||
var ed;
|
||||
|
||||
if (ed = tinyMCE.get(node.id)) {
|
||||
if (name === 'append')
|
||||
ed.setContent(ed.getContent() + value);
|
||||
else
|
||||
ed.setContent(value + ed.getContent());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
patch("both", 'attr', function(name, value) {
|
||||
if (name && name === 'value')
|
||||
return loadOrSave.call(this, value);
|
||||
});
|
||||
|
||||
$.each(['remove', 'replaceWith', 'replaceAll', 'empty'], function(i, name) {
|
||||
patch("before", name, removeEditors);
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: adapter.js 520 2008-01-07 16:30:32Z spocke $
|
||||
* $Id: adapter.js 1000 2009-02-12 13:03:40Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
@@ -7,7 +7,7 @@
|
||||
* This file contains all adapter logic needed to use prototype library as the base API for TinyMCE.
|
||||
*/
|
||||
|
||||
// #if prototype_adapter
|
||||
// #ifdef prototype_adapter
|
||||
|
||||
(function() {
|
||||
if (!window.Prototype)
|
||||
@@ -20,7 +20,7 @@
|
||||
});
|
||||
|
||||
// Patch in functions in various clases
|
||||
// Add a "#if !jquery" statement around each core API function you add below
|
||||
// Add a "#ifndefjquery" statement around each core API function you add below
|
||||
var patches = {
|
||||
'tinymce.util.JSON' : {
|
||||
serialize : function(o) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* $Id: EditorCommands.js 1042 2009-03-04 16:00:50Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function(tinymce) {
|
||||
tinymce.GlobalCommands.add('mceBlockQuote', function() {
|
||||
var ed = this, s = ed.selection, dom = ed.dom, sb, eb, n, bm, bq, r, bq2, i, nl;
|
||||
|
||||
function getBQ(e) {
|
||||
return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});
|
||||
};
|
||||
|
||||
// Get start/end block
|
||||
sb = dom.getParent(s.getStart(), dom.isBlock);
|
||||
eb = dom.getParent(s.getEnd(), dom.isBlock);
|
||||
|
||||
// Remove blockquote(s)
|
||||
if (bq = getBQ(sb)) {
|
||||
if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))
|
||||
bm = s.getBookmark();
|
||||
|
||||
// Move all elements after the end block into new bq
|
||||
if (getBQ(eb)) {
|
||||
bq2 = bq.cloneNode(false);
|
||||
|
||||
while (n = eb.nextSibling)
|
||||
bq2.appendChild(n.parentNode.removeChild(n));
|
||||
}
|
||||
|
||||
// Add new bq after
|
||||
if (bq2)
|
||||
dom.insertAfter(bq2, bq);
|
||||
|
||||
// Move all selected blocks after the current bq
|
||||
nl = s.getSelectedBlocks(sb, eb);
|
||||
for (i = nl.length - 1; i >= 0; i--) {
|
||||
dom.insertAfter(nl[i], bq);
|
||||
}
|
||||
|
||||
// Empty bq, then remove it
|
||||
if (/^\s*$/.test(bq.innerHTML))
|
||||
dom.remove(bq, 1); // Keep children so boomark restoration works correctly
|
||||
|
||||
// Empty bq, then remote it
|
||||
if (bq2 && /^\s*$/.test(bq2.innerHTML))
|
||||
dom.remove(bq2, 1); // Keep children so boomark restoration works correctly
|
||||
|
||||
if (!bm) {
|
||||
// Move caret inside empty block element
|
||||
if (!tinymce.isIE) {
|
||||
r = ed.getDoc().createRange();
|
||||
r.setStart(sb, 0);
|
||||
r.setEnd(sb, 0);
|
||||
s.setRng(r);
|
||||
} else {
|
||||
s.select(sb);
|
||||
s.collapse(0);
|
||||
|
||||
// IE misses the empty block some times element so we must move back the caret
|
||||
if (dom.getParent(s.getStart(), dom.isBlock) != sb) {
|
||||
r = s.getRng();
|
||||
r.move('character', -1);
|
||||
r.select();
|
||||
}
|
||||
}
|
||||
} else
|
||||
ed.selection.moveToBookmark(bm);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Since IE can start with a totally empty document we need to add the first bq and paragraph
|
||||
if (tinymce.isIE && !sb && !eb) {
|
||||
ed.getDoc().execCommand('Indent');
|
||||
n = getBQ(s.getNode());
|
||||
n.style.margin = n.dir = ''; // IE adds margin and dir to bq
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sb || !eb)
|
||||
return;
|
||||
|
||||
// If empty paragraph node then do not use bookmark
|
||||
if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))
|
||||
bm = s.getBookmark();
|
||||
|
||||
// Move selected block elements into a bq
|
||||
tinymce.each(s.getSelectedBlocks(getBQ(s.getStart()), getBQ(s.getEnd())), function(e) {
|
||||
// Found existing BQ add to this one
|
||||
if (e.nodeName == 'BLOCKQUOTE' && !bq) {
|
||||
bq = e;
|
||||
return;
|
||||
}
|
||||
|
||||
// No BQ found, create one
|
||||
if (!bq) {
|
||||
bq = dom.create('blockquote');
|
||||
e.parentNode.insertBefore(bq, e);
|
||||
}
|
||||
|
||||
// Add children from existing BQ
|
||||
if (e.nodeName == 'BLOCKQUOTE' && bq) {
|
||||
n = e.firstChild;
|
||||
|
||||
while (n) {
|
||||
bq.appendChild(n.cloneNode(true));
|
||||
n = n.nextSibling;
|
||||
}
|
||||
|
||||
dom.remove(e);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add non BQ element to BQ
|
||||
bq.appendChild(dom.remove(e));
|
||||
});
|
||||
|
||||
if (!bm) {
|
||||
// Move caret inside empty block element
|
||||
if (!tinymce.isIE) {
|
||||
r = ed.getDoc().createRange();
|
||||
r.setStart(sb, 0);
|
||||
r.setEnd(sb, 0);
|
||||
s.setRng(r);
|
||||
} else {
|
||||
s.select(sb);
|
||||
s.collapse(1);
|
||||
}
|
||||
} else
|
||||
s.moveToBookmark(bm);
|
||||
});
|
||||
})(tinymce);
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* $Id: EditorCommands.js 1042 2009-03-04 16:00:50Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function(tinymce) {
|
||||
tinymce.each(['Cut', 'Copy', 'Paste'], function(cmd) {
|
||||
tinymce.GlobalCommands.add(cmd, function() {
|
||||
var ed = this, doc = ed.getDoc();
|
||||
|
||||
try {
|
||||
doc.execCommand(cmd, false, null);
|
||||
|
||||
// On WebKit the command will just be ignored if it's not enabled
|
||||
if (!doc.queryCommandEnabled(cmd))
|
||||
throw 'Error';
|
||||
} catch (ex) {
|
||||
if (tinymce.isGecko) {
|
||||
ed.windowManager.confirm(ed.getLang('clipboard_msg'), function(s) {
|
||||
if (s)
|
||||
open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', '_blank');
|
||||
});
|
||||
} else
|
||||
ed.windowManager.alert(ed.getLang('clipboard_no_support'));
|
||||
}
|
||||
});
|
||||
});
|
||||
})(tinymce);
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* $Id: EditorCommands.js 1042 2009-03-04 16:00:50Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function(tinymce) {
|
||||
tinymce.GlobalCommands.add('InsertHorizontalRule', function() {
|
||||
if (tinymce.isOpera)
|
||||
return this.getDoc().execCommand('InsertHorizontalRule', false, '');
|
||||
|
||||
this.selection.setContent('<hr />');
|
||||
});
|
||||
})(tinymce);
|
||||
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* $Id: EditorCommands.js 1042 2009-03-04 16:00:50Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function(tinymce) {
|
||||
function processRange(dom, start, end, callback) {
|
||||
var ancestor, n, startPoint, endPoint, sib;
|
||||
|
||||
function findEndPoint(n, c) {
|
||||
do {
|
||||
if (n.parentNode == c)
|
||||
return n;
|
||||
|
||||
n = n.parentNode;
|
||||
} while(n);
|
||||
};
|
||||
|
||||
function process(n) {
|
||||
callback(n);
|
||||
tinymce.walk(n, callback, 'childNodes');
|
||||
};
|
||||
|
||||
// Find common ancestor and end points
|
||||
ancestor = dom.findCommonAncestor(start, end);
|
||||
startPoint = findEndPoint(start, ancestor) || start;
|
||||
endPoint = findEndPoint(end, ancestor) || end;
|
||||
|
||||
// Process left leaf
|
||||
for (n = start; n && n != startPoint; n = n.parentNode) {
|
||||
for (sib = n.nextSibling; sib; sib = sib.nextSibling)
|
||||
process(sib);
|
||||
}
|
||||
|
||||
// Process middle from start to end point
|
||||
if (startPoint != endPoint) {
|
||||
for (n = startPoint.nextSibling; n && n != endPoint; n = n.nextSibling)
|
||||
process(n);
|
||||
} else
|
||||
process(startPoint);
|
||||
|
||||
// Process right leaf
|
||||
for (n = end; n && n != endPoint; n = n.parentNode) {
|
||||
for (sib = n.previousSibling; sib; sib = sib.previousSibling)
|
||||
process(sib);
|
||||
}
|
||||
};
|
||||
|
||||
tinymce.GlobalCommands.add('RemoveFormat', function() {
|
||||
var ed = this, dom = ed.dom, s = ed.selection, r = s.getRng(1), nodes = [], bm, start, end, sc, so, ec, eo, n;
|
||||
|
||||
function findFormatRoot(n) {
|
||||
var sp;
|
||||
|
||||
dom.getParent(n, function(n) {
|
||||
if (dom.is(n, ed.getParam('removeformat_selector')))
|
||||
sp = n;
|
||||
|
||||
return dom.isBlock(n);
|
||||
}, ed.getBody());
|
||||
|
||||
return sp;
|
||||
};
|
||||
|
||||
function collect(n) {
|
||||
if (dom.is(n, ed.getParam('removeformat_selector')))
|
||||
nodes.push(n);
|
||||
};
|
||||
|
||||
function walk(n) {
|
||||
collect(n);
|
||||
tinymce.walk(n, collect, 'childNodes');
|
||||
};
|
||||
|
||||
bm = s.getBookmark();
|
||||
sc = r.startContainer;
|
||||
ec = r.endContainer;
|
||||
so = r.startOffset;
|
||||
eo = r.endOffset;
|
||||
sc = sc.nodeType == 1 ? sc.childNodes[Math.min(so, sc.childNodes.length - 1)] : sc;
|
||||
ec = ec.nodeType == 1 ? ec.childNodes[Math.min(so == eo ? eo : eo - 1, ec.childNodes.length - 1)] : ec;
|
||||
|
||||
// Same container
|
||||
if (sc == ec) { // TEXT_NODE
|
||||
start = findFormatRoot(sc);
|
||||
|
||||
// Handle single text node
|
||||
if (sc.nodeType == 3) {
|
||||
if (start && start.nodeType == 1) { // ELEMENT
|
||||
n = sc.splitText(so);
|
||||
n.splitText(eo - so);
|
||||
dom.split(start, n);
|
||||
|
||||
s.moveToBookmark(bm);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle single element
|
||||
walk(dom.split(start, sc) || sc);
|
||||
} else {
|
||||
// Find start/end format root
|
||||
start = findFormatRoot(sc);
|
||||
end = findFormatRoot(ec);
|
||||
|
||||
// Split start text node
|
||||
if (start) {
|
||||
if (sc.nodeType == 3) { // TEXT
|
||||
// Since IE doesn't support white space nodes in the DOM we need to
|
||||
// add this invisible character so that the splitText function can split the contents
|
||||
if (so == sc.nodeValue.length)
|
||||
sc.nodeValue += '\uFEFF'; // Yet another pesky IE fix
|
||||
|
||||
sc = sc.splitText(so);
|
||||
}
|
||||
}
|
||||
|
||||
// Split end text node
|
||||
if (end) {
|
||||
if (ec.nodeType == 3) // TEXT
|
||||
ec.splitText(eo);
|
||||
}
|
||||
|
||||
// If the start and end format root is the same then we need to wrap
|
||||
// the end node in a span since the split calls might change the reference
|
||||
// Example: <p><b><em>x[yz<span>---</span>12]3</em></b></p>
|
||||
if (start && start == end)
|
||||
dom.replace(dom.create('span', {id : '__end'}, ec.cloneNode(true)), ec);
|
||||
|
||||
// Split all start containers down to the format root
|
||||
if (start)
|
||||
start = dom.split(start, sc);
|
||||
else
|
||||
start = sc;
|
||||
|
||||
// If there is a span wrapper use that one instead
|
||||
if (n = dom.get('__end')) {
|
||||
ec = n;
|
||||
end = findFormatRoot(ec);
|
||||
}
|
||||
|
||||
// Split all end containers down to the format root
|
||||
if (end)
|
||||
end = dom.split(end, ec);
|
||||
else
|
||||
end = ec;
|
||||
|
||||
// Collect nodes in between
|
||||
processRange(dom, start, end, collect);
|
||||
|
||||
// Remove invisible character for IE workaround if we find it
|
||||
if (sc.nodeValue == '\uFEFF')
|
||||
sc.nodeValue = '';
|
||||
|
||||
// Process start/end container elements
|
||||
walk(ec);
|
||||
walk(sc);
|
||||
}
|
||||
|
||||
// Remove all collected nodes
|
||||
tinymce.each(nodes, function(n) {
|
||||
dom.remove(n, 1);
|
||||
});
|
||||
|
||||
// Remove leftover wrapper
|
||||
dom.remove('__end', 1);
|
||||
|
||||
s.moveToBookmark(bm);
|
||||
});
|
||||
})(tinymce);
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* $Id: EditorCommands.js 1042 2009-03-04 16:00:50Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var cmds = tinymce.GlobalCommands;
|
||||
|
||||
cmds.add(['mceEndUndoLevel', 'mceAddUndoLevel'], function() {
|
||||
this.undoManager.add();
|
||||
});
|
||||
|
||||
cmds.add('Undo', function() {
|
||||
var ed = this;
|
||||
|
||||
if (ed.settings.custom_undo_redo) {
|
||||
ed.undoManager.undo();
|
||||
ed.nodeChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // Run browser command
|
||||
});
|
||||
|
||||
cmds.add('Redo', function() {
|
||||
var ed = this;
|
||||
|
||||
if (ed.settings.custom_undo_redo) {
|
||||
ed.undoManager.redo();
|
||||
ed.nodeChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // Run browser command
|
||||
});
|
||||
})();
|
||||
+509
-381
File diff suppressed because it is too large
Load Diff
+21
-24
@@ -1,24 +1,26 @@
|
||||
/**
|
||||
* $Id: Element.js 520 2008-01-07 16:30:32Z spocke $
|
||||
* $Id: Element.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var each = tinymce.each;
|
||||
|
||||
/**#@+
|
||||
* @class Element class, this enables element blocking in IE. Element blocking is a method to block out select blockes that
|
||||
/**
|
||||
* Element class, this enables element blocking in IE. Element blocking is a method to block out select blockes that
|
||||
* gets visible though DIVs on IE 6 it uses a iframe for this blocking. This class also shortens the length of some DOM API calls
|
||||
* since it's bound to an element.
|
||||
* @member tinymce.dom.Element
|
||||
*
|
||||
* @class tinymce.dom.Element
|
||||
*/
|
||||
tinymce.create('tinymce.dom.Element', {
|
||||
/**
|
||||
* Constructs a new Element instance. Consult the Wiki for more details on this class.
|
||||
*
|
||||
* @constructor
|
||||
* @method Element
|
||||
* @param {String} Element ID to bind/execute methods on.
|
||||
* @param {Object} Optional settings name/value collection.
|
||||
*/
|
||||
@@ -58,33 +60,23 @@
|
||||
'get'
|
||||
], function(k) {
|
||||
t[k] = function() {
|
||||
var a = arguments, o;
|
||||
var a = [id], i;
|
||||
|
||||
// Opera fails
|
||||
if (tinymce.isOpera) {
|
||||
a = [id];
|
||||
for (i = 0; i < arguments.length; i++)
|
||||
a.push(arguments[i]);
|
||||
|
||||
each(arguments, function(v) {
|
||||
a.push(v);
|
||||
});
|
||||
} else
|
||||
Array.prototype.unshift.call(a, el || id);
|
||||
|
||||
o = dom[k].apply(dom, a);
|
||||
a = dom[k].apply(dom, a);
|
||||
t.update(k);
|
||||
|
||||
return o;
|
||||
return a;
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds a event handler to the element.
|
||||
*
|
||||
* @method on
|
||||
* @param {String} n Event name like for example "click".
|
||||
* @param {function} f Function to execute on the specified event.
|
||||
* @param {Object} s Optional scope to execute function on.
|
||||
@@ -97,6 +89,7 @@
|
||||
/**
|
||||
* Returns the absolute X, Y cordinate of the element.
|
||||
*
|
||||
* @method getXY
|
||||
* @return {Object} Objext with x, y cordinate fields.
|
||||
*/
|
||||
getXY : function() {
|
||||
@@ -109,6 +102,7 @@
|
||||
/**
|
||||
* Returns the size of the element by a object with w and h fields.
|
||||
*
|
||||
* @method getSize
|
||||
* @return {Object} Object with element size with a w and h field.
|
||||
*/
|
||||
getSize : function() {
|
||||
@@ -123,6 +117,7 @@
|
||||
/**
|
||||
* Moves the element to a specific absolute position.
|
||||
*
|
||||
* @method moveTo
|
||||
* @param {Number} x X cordinate of element position.
|
||||
* @param {Number} y Y cordinate of element position.
|
||||
*/
|
||||
@@ -133,6 +128,7 @@
|
||||
/**
|
||||
* Moves the element relative to the current position.
|
||||
*
|
||||
* @method moveBy
|
||||
* @param {Number} x Relative X cordinate of element position.
|
||||
* @param {Number} y Relative Y cordinate of element position.
|
||||
*/
|
||||
@@ -145,6 +141,7 @@
|
||||
/**
|
||||
* Resizes the element to a specific size.
|
||||
*
|
||||
* @method resizeTo
|
||||
* @param {Number} w New width of element.
|
||||
* @param {Numner} h New height of element.
|
||||
*/
|
||||
@@ -155,6 +152,7 @@
|
||||
/**
|
||||
* Resizes the element relative to the current sizeto a specific size.
|
||||
*
|
||||
* @method resizeBy
|
||||
* @param {Number} w Relative width of element.
|
||||
* @param {Numner} h Relative height of element.
|
||||
*/
|
||||
@@ -167,6 +165,7 @@
|
||||
/**
|
||||
* Updates the element blocker in IE6 based on the style information of the element.
|
||||
*
|
||||
* @method update
|
||||
* @param {String} k Optional function key. Used internally.
|
||||
*/
|
||||
update : function(k) {
|
||||
@@ -200,7 +199,5 @@
|
||||
dom.setStyle(b, 'zIndex', parseInt(t.getStyle('zIndex', 1) || 0) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
/**
|
||||
* $Id: EventUtils.js 1190 2009-08-12 17:59:29Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function(tinymce) {
|
||||
// Shorten names
|
||||
var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event;
|
||||
|
||||
/**
|
||||
* This class handles DOM events in a cross platform fasion it also keeps track of element
|
||||
* and handler references to be able to clean elements to reduce IE memory leaks.
|
||||
*
|
||||
* @class tinymce.dom.EventUtils
|
||||
*/
|
||||
tinymce.create('tinymce.dom.EventUtils', {
|
||||
/**
|
||||
* Constructs a new EventUtils instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method EventUtils
|
||||
*/
|
||||
EventUtils : function() {
|
||||
this.inits = [];
|
||||
this.events = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds an event handler to the specified object.
|
||||
*
|
||||
* @method add
|
||||
* @param {Element/Document/Window/Array/String} o Object or element id string to add event handler to or an array of elements/ids/documents.
|
||||
* @param {String/Array} n Name of event handler to add for example: click.
|
||||
* @param {function} f Function to execute when the event occurs.
|
||||
* @param {Object} s Optional scope to execute the function in.
|
||||
* @return {function} Function callback handler the same as the one passed in.
|
||||
*/
|
||||
add : function(o, n, f, s) {
|
||||
var cb, t = this, el = t.events, r;
|
||||
|
||||
if (n instanceof Array) {
|
||||
r = [];
|
||||
|
||||
each(n, function(n) {
|
||||
r.push(t.add(o, n, f, s));
|
||||
});
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// Handle array
|
||||
if (o && o.hasOwnProperty && o instanceof Array) {
|
||||
r = [];
|
||||
|
||||
each(o, function(o) {
|
||||
o = DOM.get(o);
|
||||
r.push(t.add(o, n, f, s));
|
||||
});
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
o = DOM.get(o);
|
||||
|
||||
if (!o)
|
||||
return;
|
||||
|
||||
// Setup event callback
|
||||
cb = function(e) {
|
||||
// Is all events disabled
|
||||
if (t.disabled)
|
||||
return;
|
||||
|
||||
e = e || window.event;
|
||||
|
||||
// Patch in target, preventDefault and stopPropagation in IE it's W3C valid
|
||||
if (e && isIE) {
|
||||
if (!e.target)
|
||||
e.target = e.srcElement;
|
||||
|
||||
// Patch in preventDefault, stopPropagation methods for W3C compatibility
|
||||
tinymce.extend(e, t._stoppers);
|
||||
}
|
||||
|
||||
if (!s)
|
||||
return f(e);
|
||||
|
||||
return f.call(s, e);
|
||||
};
|
||||
|
||||
if (n == 'unload') {
|
||||
tinymce.unloads.unshift({func : cb});
|
||||
return cb;
|
||||
}
|
||||
|
||||
if (n == 'init') {
|
||||
if (t.domLoaded)
|
||||
cb();
|
||||
else
|
||||
t.inits.push(cb);
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
// Store away listener reference
|
||||
el.push({
|
||||
obj : o,
|
||||
name : n,
|
||||
func : f,
|
||||
cfunc : cb,
|
||||
scope : s
|
||||
});
|
||||
|
||||
t._add(o, n, cb);
|
||||
|
||||
return f;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the specified event handler by name and function from a element or collection of elements.
|
||||
*
|
||||
* @method remove
|
||||
* @param {String/Element/Array} o Element ID string or HTML element or an array of elements or ids to remove handler from.
|
||||
* @param {String} n Event handler name like for example: "click"
|
||||
* @param {function} f Function to remove.
|
||||
* @return {bool/Array} Bool state if true if the handler was removed or an array with states if multiple elements where passed in.
|
||||
*/
|
||||
remove : function(o, n, f) {
|
||||
var t = this, a = t.events, s = false, r;
|
||||
|
||||
// Handle array
|
||||
if (o && o.hasOwnProperty && o instanceof Array) {
|
||||
r = [];
|
||||
|
||||
each(o, function(o) {
|
||||
o = DOM.get(o);
|
||||
r.push(t.remove(o, n, f));
|
||||
});
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
o = DOM.get(o);
|
||||
|
||||
each(a, function(e, i) {
|
||||
if (e.obj == o && e.name == n && (!f || (e.func == f || e.cfunc == f))) {
|
||||
a.splice(i, 1);
|
||||
t._remove(o, n, e.cfunc);
|
||||
s = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return s;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears all events of a specific object.
|
||||
*
|
||||
* @method clear
|
||||
* @param {Object} o DOM element or object to remove all events from.
|
||||
*/
|
||||
clear : function(o) {
|
||||
var t = this, a = t.events, i, e;
|
||||
|
||||
if (o) {
|
||||
o = DOM.get(o);
|
||||
|
||||
for (i = a.length - 1; i >= 0; i--) {
|
||||
e = a[i];
|
||||
|
||||
if (e.obj === o) {
|
||||
t._remove(e.obj, e.name, e.cfunc);
|
||||
e.obj = e.cfunc = null;
|
||||
a.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Cancels an event for both bubbeling and the default browser behavior.
|
||||
*
|
||||
* @method cancel
|
||||
* @param {Event} e Event object to cancel.
|
||||
* @return {Boolean} Always false.
|
||||
*/
|
||||
cancel : function(e) {
|
||||
if (!e)
|
||||
return false;
|
||||
|
||||
this.stop(e);
|
||||
|
||||
return this.prevent(e);
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops propogation/bubbeling of an event.
|
||||
*
|
||||
* @method stop
|
||||
* @param {Event} e Event to cancel bubbeling on.
|
||||
* @return {Boolean} Always false.
|
||||
*/
|
||||
stop : function(e) {
|
||||
if (e.stopPropagation)
|
||||
e.stopPropagation();
|
||||
else
|
||||
e.cancelBubble = true;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Prevent default browser behvaior of an event.
|
||||
*
|
||||
* @method prevent
|
||||
* @param {Event} e Event to prevent default browser behvaior of an event.
|
||||
* @return {Boolean} Always false.
|
||||
*/
|
||||
prevent : function(e) {
|
||||
if (e.preventDefault)
|
||||
e.preventDefault();
|
||||
else
|
||||
e.returnValue = false;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroys the instance.
|
||||
*
|
||||
* @method destroy
|
||||
*/
|
||||
destroy : function() {
|
||||
var t = this;
|
||||
|
||||
each(t.events, function(e, i) {
|
||||
t._remove(e.obj, e.name, e.cfunc);
|
||||
e.obj = e.cfunc = null;
|
||||
});
|
||||
|
||||
t.events = [];
|
||||
t = null;
|
||||
},
|
||||
|
||||
_add : function(o, n, f) {
|
||||
if (o.attachEvent)
|
||||
o.attachEvent('on' + n, f);
|
||||
else if (o.addEventListener)
|
||||
o.addEventListener(n, f, false);
|
||||
else
|
||||
o['on' + n] = f;
|
||||
},
|
||||
|
||||
_remove : function(o, n, f) {
|
||||
if (o) {
|
||||
try {
|
||||
if (o.detachEvent)
|
||||
o.detachEvent('on' + n, f);
|
||||
else if (o.removeEventListener)
|
||||
o.removeEventListener(n, f, false);
|
||||
else
|
||||
o['on' + n] = null;
|
||||
} catch (ex) {
|
||||
// Might fail with permission denined on IE so we just ignore that
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_pageInit : function(win) {
|
||||
var t = this;
|
||||
|
||||
// Keep it from running more than once
|
||||
if (t.domLoaded)
|
||||
return;
|
||||
|
||||
t.domLoaded = true;
|
||||
|
||||
each(t.inits, function(c) {
|
||||
c();
|
||||
});
|
||||
|
||||
t.inits = [];
|
||||
},
|
||||
|
||||
_wait : function(win) {
|
||||
var t = this, doc = win.document;
|
||||
|
||||
// No need since the document is already loaded
|
||||
if (win.tinyMCE_GZ && tinyMCE_GZ.loaded) {
|
||||
t.domLoaded = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Use IE method
|
||||
if (doc.attachEvent) {
|
||||
doc.attachEvent("onreadystatechange", function() {
|
||||
if (doc.readyState === "complete") {
|
||||
doc.detachEvent("onreadystatechange", arguments.callee);
|
||||
t._pageInit(win);
|
||||
}
|
||||
});
|
||||
|
||||
if (doc.documentElement.doScroll && win == win.top) {
|
||||
(function() {
|
||||
if (t.domLoaded)
|
||||
return;
|
||||
|
||||
try {
|
||||
// If IE is used, use the trick by Diego Perini
|
||||
// http://javascript.nwbox.com/IEContentLoaded/
|
||||
doc.documentElement.doScroll("left");
|
||||
} catch (ex) {
|
||||
setTimeout(arguments.callee, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
t._pageInit(win);
|
||||
})();
|
||||
}
|
||||
} else if (doc.addEventListener) {
|
||||
t._add(win, 'DOMContentLoaded', function() {
|
||||
t._pageInit(win);
|
||||
});
|
||||
}
|
||||
|
||||
t._add(win, 'load', function() {
|
||||
t._pageInit(win);
|
||||
});
|
||||
},
|
||||
|
||||
_stoppers : {
|
||||
preventDefault : function() {
|
||||
this.returnValue = false;
|
||||
},
|
||||
|
||||
stopPropagation : function() {
|
||||
this.cancelBubble = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Instance of EventUtils for the current document.
|
||||
*
|
||||
* @property Event
|
||||
* @member tinymce.dom
|
||||
* @type tinymce.dom.EventUtils
|
||||
*/
|
||||
Event = tinymce.dom.Event = new tinymce.dom.EventUtils();
|
||||
|
||||
// Dispatch DOM content loaded event for IE and Safari
|
||||
Event._wait(window);
|
||||
|
||||
tinymce.addUnload(function() {
|
||||
Event.destroy();
|
||||
});
|
||||
})(tinymce);
|
||||
+721
@@ -0,0 +1,721 @@
|
||||
/**
|
||||
* $Id: Range.js 1072 2009-04-02 19:57:45Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*
|
||||
* setEnd IMPLEMENTED
|
||||
* setStartBefore IMPLEMENTED
|
||||
* setStartAfter IMPLEMENTED
|
||||
* setEndBefore IMPLEMENTED
|
||||
* setEndAfter IMPLEMENTED
|
||||
* collapse IMPLEMENTED
|
||||
* selectNode IMPLEMENTED
|
||||
* selectNodeContents IMPLEMENTED
|
||||
* compareBoundaryPoints IMPLEMENTED
|
||||
* deleteContents IMPLEMENTED
|
||||
* extractContents IMPLEMENTED
|
||||
* cloneContents IMPLEMENTED
|
||||
* insertNode IMPLEMENTED
|
||||
* surroundContents IMPLEMENTED
|
||||
* cloneRange IMPLEMENTED
|
||||
* toString NOT IMPLEMENTED
|
||||
* detach NOT IMPLEMENTED
|
||||
*/
|
||||
|
||||
(function(ns) {
|
||||
// Traverse constants
|
||||
var EXTRACT = 0, CLONE = 1, DELETE = 2, extend = tinymce.extend;
|
||||
|
||||
function indexOf(child, parent) {
|
||||
var i, node;
|
||||
|
||||
if (child.parentNode != parent)
|
||||
return -1;
|
||||
|
||||
for (node = parent.firstChild, i = 0; node != child; node = node.nextSibling)
|
||||
i++;
|
||||
|
||||
return i;
|
||||
};
|
||||
|
||||
function nodeIndex(n) {
|
||||
var i = 0;
|
||||
|
||||
while (n.previousSibling) {
|
||||
i++;
|
||||
n = n.previousSibling;
|
||||
}
|
||||
|
||||
return i;
|
||||
};
|
||||
|
||||
function getSelectedNode(container, offset) {
|
||||
var child;
|
||||
|
||||
if (container.nodeType == 3 /* TEXT_NODE */)
|
||||
return container;
|
||||
|
||||
if (offset < 0)
|
||||
return container;
|
||||
|
||||
child = container.firstChild;
|
||||
while (child != null && offset > 0) {
|
||||
--offset;
|
||||
child = child.nextSibling;
|
||||
}
|
||||
|
||||
if (child != null)
|
||||
return child;
|
||||
|
||||
return container;
|
||||
};
|
||||
|
||||
// Range constructor
|
||||
function Range(dom) {
|
||||
var d = dom.doc;
|
||||
|
||||
extend(this, {
|
||||
dom : dom,
|
||||
|
||||
// Inital states
|
||||
startContainer : d,
|
||||
startOffset : 0,
|
||||
endContainer : d,
|
||||
endOffset : 0,
|
||||
collapsed : true,
|
||||
commonAncestorContainer : d,
|
||||
|
||||
// Range constants
|
||||
START_TO_START : 0,
|
||||
START_TO_END : 1,
|
||||
END_TO_END : 2,
|
||||
END_TO_START : 3
|
||||
});
|
||||
};
|
||||
|
||||
// Add range methods
|
||||
extend(Range.prototype, {
|
||||
setStart : function(n, o) {
|
||||
this._setEndPoint(true, n, o);
|
||||
},
|
||||
|
||||
setEnd : function(n, o) {
|
||||
this._setEndPoint(false, n, o);
|
||||
},
|
||||
|
||||
setStartBefore : function(n) {
|
||||
this.setStart(n.parentNode, nodeIndex(n));
|
||||
},
|
||||
|
||||
setStartAfter : function(n) {
|
||||
this.setStart(n.parentNode, nodeIndex(n) + 1);
|
||||
},
|
||||
|
||||
setEndBefore : function(n) {
|
||||
this.setEnd(n.parentNode, nodeIndex(n));
|
||||
},
|
||||
|
||||
setEndAfter : function(n) {
|
||||
this.setEnd(n.parentNode, nodeIndex(n) + 1);
|
||||
},
|
||||
|
||||
collapse : function(ts) {
|
||||
var t = this;
|
||||
|
||||
if (ts) {
|
||||
t.endContainer = t.startContainer;
|
||||
t.endOffset = t.startOffset;
|
||||
} else {
|
||||
t.startContainer = t.endContainer;
|
||||
t.startOffset = t.endOffset;
|
||||
}
|
||||
|
||||
t.collapsed = true;
|
||||
},
|
||||
|
||||
selectNode : function(n) {
|
||||
this.setStartBefore(n);
|
||||
this.setEndAfter(n);
|
||||
},
|
||||
|
||||
selectNodeContents : function(n) {
|
||||
this.setStart(n, 0);
|
||||
this.setEnd(n, n.nodeType === 1 ? n.childNodes.length : n.nodeValue.length);
|
||||
},
|
||||
|
||||
compareBoundaryPoints : function(h, r) {
|
||||
var t = this, sc = t.startContainer, so = t.startOffset, ec = t.endContainer, eo = t.endOffset;
|
||||
|
||||
// Check START_TO_START
|
||||
if (h === 0)
|
||||
return t._compareBoundaryPoints(sc, so, sc, so);
|
||||
|
||||
// Check START_TO_END
|
||||
if (h === 1)
|
||||
return t._compareBoundaryPoints(sc, so, ec, eo);
|
||||
|
||||
// Check END_TO_END
|
||||
if (h === 2)
|
||||
return t._compareBoundaryPoints(ec, eo, ec, eo);
|
||||
|
||||
// Check END_TO_START
|
||||
if (h === 3)
|
||||
return t._compareBoundaryPoints(ec, eo, sc, so);
|
||||
},
|
||||
|
||||
deleteContents : function() {
|
||||
this._traverse(DELETE);
|
||||
},
|
||||
|
||||
extractContents : function() {
|
||||
return this._traverse(EXTRACT);
|
||||
},
|
||||
|
||||
cloneContents : function() {
|
||||
return this._traverse(CLONE);
|
||||
},
|
||||
|
||||
insertNode : function(n) {
|
||||
var t = this, nn, o;
|
||||
|
||||
// Node is TEXT_NODE or CDATA
|
||||
if (n.nodeType === 3 || n.nodeType === 4) {
|
||||
nn = t.startContainer.splitText(t.startOffset);
|
||||
t.startContainer.parentNode.insertBefore(n, nn);
|
||||
} else {
|
||||
// Insert element node
|
||||
if (t.startContainer.childNodes.length > 0)
|
||||
o = t.startContainer.childNodes[t.startOffset];
|
||||
|
||||
t.startContainer.insertBefore(n, o);
|
||||
}
|
||||
},
|
||||
|
||||
surroundContents : function(n) {
|
||||
var t = this, f = t.extractContents();
|
||||
|
||||
t.insertNode(n);
|
||||
n.appendChild(f);
|
||||
t.selectNode(n);
|
||||
},
|
||||
|
||||
cloneRange : function() {
|
||||
var t = this;
|
||||
|
||||
return extend(new Range(t.dom), {
|
||||
startContainer : t.startContainer,
|
||||
startOffset : t.startOffset,
|
||||
endContainer : t.endContainer,
|
||||
endOffset : t.endOffset,
|
||||
collapsed : t.collapsed,
|
||||
commonAncestorContainer : t.commonAncestorContainer
|
||||
});
|
||||
},
|
||||
|
||||
/*
|
||||
detach : function() {
|
||||
// Not implemented
|
||||
},
|
||||
*/
|
||||
// Internal methods
|
||||
|
||||
_isCollapsed : function() {
|
||||
return (this.startContainer == this.endContainer && this.startOffset == this.endOffset);
|
||||
},
|
||||
|
||||
_compareBoundaryPoints : function (containerA, offsetA, containerB, offsetB) {
|
||||
var c, offsetC, n, cmnRoot, childA, childB;
|
||||
|
||||
// In the first case the boundary-points have the same container. A is before B
|
||||
// if its offset is less than the offset of B, A is equal to B if its offset is
|
||||
// equal to the offset of B, and A is after B if its offset is greater than the
|
||||
// offset of B.
|
||||
if (containerA == containerB) {
|
||||
if (offsetA == offsetB) {
|
||||
return 0; // equal
|
||||
} else if (offsetA < offsetB) {
|
||||
return -1; // before
|
||||
} else {
|
||||
return 1; // after
|
||||
}
|
||||
}
|
||||
|
||||
// In the second case a child node C of the container of A is an ancestor
|
||||
// container of B. In this case, A is before B if the offset of A is less than or
|
||||
// equal to the index of the child node C and A is after B otherwise.
|
||||
c = containerB;
|
||||
while (c && c.parentNode != containerA) {
|
||||
c = c.parentNode;
|
||||
}
|
||||
if (c) {
|
||||
offsetC = 0;
|
||||
n = containerA.firstChild;
|
||||
|
||||
while (n != c && offsetC < offsetA) {
|
||||
offsetC++;
|
||||
n = n.nextSibling;
|
||||
}
|
||||
|
||||
if (offsetA <= offsetC) {
|
||||
return -1; // before
|
||||
} else {
|
||||
return 1; // after
|
||||
}
|
||||
}
|
||||
|
||||
// In the third case a child node C of the container of B is an ancestor container
|
||||
// of A. In this case, A is before B if the index of the child node C is less than
|
||||
// the offset of B and A is after B otherwise.
|
||||
c = containerA;
|
||||
while (c && c.parentNode != containerB) {
|
||||
c = c.parentNode;
|
||||
}
|
||||
|
||||
if (c) {
|
||||
offsetC = 0;
|
||||
n = containerB.firstChild;
|
||||
|
||||
while (n != c && offsetC < offsetB) {
|
||||
offsetC++;
|
||||
n = n.nextSibling;
|
||||
}
|
||||
|
||||
if (offsetC < offsetB) {
|
||||
return -1; // before
|
||||
} else {
|
||||
return 1; // after
|
||||
}
|
||||
}
|
||||
|
||||
// In the fourth case, none of three other cases hold: the containers of A and B
|
||||
// are siblings or descendants of sibling nodes. In this case, A is before B if
|
||||
// the container of A is before the container of B in a pre-order traversal of the
|
||||
// Ranges' context tree and A is after B otherwise.
|
||||
cmnRoot = this.dom.findCommonAncestor(containerA, containerB);
|
||||
childA = containerA;
|
||||
|
||||
while (childA && childA.parentNode != cmnRoot) {
|
||||
childA = childA.parentNode;
|
||||
}
|
||||
|
||||
if (!childA) {
|
||||
childA = cmnRoot;
|
||||
}
|
||||
|
||||
childB = containerB;
|
||||
while (childB && childB.parentNode != cmnRoot) {
|
||||
childB = childB.parentNode;
|
||||
}
|
||||
|
||||
if (!childB) {
|
||||
childB = cmnRoot;
|
||||
}
|
||||
|
||||
if (childA == childB) {
|
||||
return 0; // equal
|
||||
}
|
||||
|
||||
n = cmnRoot.firstChild;
|
||||
while (n) {
|
||||
if (n == childA) {
|
||||
return -1; // before
|
||||
}
|
||||
|
||||
if (n == childB) {
|
||||
return 1; // after
|
||||
}
|
||||
|
||||
n = n.nextSibling;
|
||||
}
|
||||
},
|
||||
|
||||
_setEndPoint : function(st, n, o) {
|
||||
var t = this, ec, sc;
|
||||
|
||||
if (st) {
|
||||
t.startContainer = n;
|
||||
t.startOffset = o;
|
||||
} else {
|
||||
t.endContainer = n;
|
||||
t.endOffset = o;
|
||||
}
|
||||
|
||||
// If one boundary-point of a Range is set to have a root container
|
||||
// other than the current one for the Range, the Range is collapsed to
|
||||
// the new position. This enforces the restriction that both boundary-
|
||||
// points of a Range must have the same root container.
|
||||
ec = t.endContainer;
|
||||
while (ec.parentNode)
|
||||
ec = ec.parentNode;
|
||||
|
||||
sc = t.startContainer;
|
||||
while (sc.parentNode)
|
||||
sc = sc.parentNode;
|
||||
|
||||
if (sc != ec) {
|
||||
t.collapse(st);
|
||||
} else {
|
||||
// The start position of a Range is guaranteed to never be after the
|
||||
// end position. To enforce this restriction, if the start is set to
|
||||
// be at a position after the end, the Range is collapsed to that
|
||||
// position.
|
||||
if (t._compareBoundaryPoints(t.startContainer, t.startOffset, t.endContainer, t.endOffset) > 0)
|
||||
t.collapse(st);
|
||||
}
|
||||
|
||||
t.collapsed = t._isCollapsed();
|
||||
t.commonAncestorContainer = t.dom.findCommonAncestor(t.startContainer, t.endContainer);
|
||||
},
|
||||
|
||||
// This code is heavily "inspired" by the Apache Xerces implementation. I hope they don't mind. :)
|
||||
|
||||
_traverse : function(how) {
|
||||
var t = this, c, endContainerDepth = 0, startContainerDepth = 0, p, depthDiff, startNode, endNode, sp, ep;
|
||||
|
||||
if (t.startContainer == t.endContainer)
|
||||
return t._traverseSameContainer(how);
|
||||
|
||||
for (c = t.endContainer, p = c.parentNode; p != null; c = p, p = p.parentNode) {
|
||||
if (p == t.startContainer)
|
||||
return t._traverseCommonStartContainer(c, how);
|
||||
|
||||
++endContainerDepth;
|
||||
}
|
||||
|
||||
for (c = t.startContainer, p = c.parentNode; p != null; c = p, p = p.parentNode) {
|
||||
if (p == t.endContainer)
|
||||
return t._traverseCommonEndContainer(c, how);
|
||||
|
||||
++startContainerDepth;
|
||||
}
|
||||
|
||||
depthDiff = startContainerDepth - endContainerDepth;
|
||||
|
||||
startNode = t.startContainer;
|
||||
while (depthDiff > 0) {
|
||||
startNode = startNode.parentNode;
|
||||
depthDiff--;
|
||||
}
|
||||
|
||||
endNode = t.endContainer;
|
||||
while (depthDiff < 0) {
|
||||
endNode = endNode.parentNode;
|
||||
depthDiff++;
|
||||
}
|
||||
|
||||
// ascend the ancestor hierarchy until we have a common parent.
|
||||
for (sp = startNode.parentNode, ep = endNode.parentNode; sp != ep; sp = sp.parentNode, ep = ep.parentNode) {
|
||||
startNode = sp;
|
||||
endNode = ep;
|
||||
}
|
||||
|
||||
return t._traverseCommonAncestors(startNode, endNode, how);
|
||||
},
|
||||
|
||||
_traverseSameContainer : function(how) {
|
||||
var t = this, frag, s, sub, n, cnt, sibling, xferNode;
|
||||
|
||||
if (how != DELETE)
|
||||
frag = t.dom.doc.createDocumentFragment();
|
||||
|
||||
// If selection is empty, just return the fragment
|
||||
if (t.startOffset == t.endOffset)
|
||||
return frag;
|
||||
|
||||
// Text node needs special case handling
|
||||
if (t.startContainer.nodeType == 3 /* TEXT_NODE */) {
|
||||
// get the substring
|
||||
s = t.startContainer.nodeValue;
|
||||
sub = s.substring(t.startOffset, t.endOffset);
|
||||
|
||||
// set the original text node to its new value
|
||||
if (how != CLONE) {
|
||||
t.startContainer.deleteData(t.startOffset, t.endOffset - t.startOffset);
|
||||
|
||||
// Nothing is partially selected, so collapse to start point
|
||||
t.collapse(true);
|
||||
}
|
||||
|
||||
if (how == DELETE)
|
||||
return null;
|
||||
|
||||
frag.appendChild(t.dom.doc.createTextNode(sub));
|
||||
return frag;
|
||||
}
|
||||
|
||||
// Copy nodes between the start/end offsets.
|
||||
n = getSelectedNode(t.startContainer, t.startOffset);
|
||||
cnt = t.endOffset - t.startOffset;
|
||||
|
||||
while (cnt > 0) {
|
||||
sibling = n.nextSibling;
|
||||
xferNode = t._traverseFullySelected(n, how);
|
||||
|
||||
if (frag)
|
||||
frag.appendChild( xferNode );
|
||||
|
||||
--cnt;
|
||||
n = sibling;
|
||||
}
|
||||
|
||||
// Nothing is partially selected, so collapse to start point
|
||||
if (how != CLONE)
|
||||
t.collapse(true);
|
||||
|
||||
return frag;
|
||||
},
|
||||
|
||||
_traverseCommonStartContainer : function(endAncestor, how) {
|
||||
var t = this, frag, n, endIdx, cnt, sibling, xferNode;
|
||||
|
||||
if (how != DELETE)
|
||||
frag = t.dom.doc.createDocumentFragment();
|
||||
|
||||
n = t._traverseRightBoundary(endAncestor, how);
|
||||
|
||||
if (frag)
|
||||
frag.appendChild(n);
|
||||
|
||||
endIdx = indexOf(endAncestor, t.startContainer);
|
||||
cnt = endIdx - t.startOffset;
|
||||
|
||||
if (cnt <= 0) {
|
||||
// Collapse to just before the endAncestor, which
|
||||
// is partially selected.
|
||||
if (how != CLONE) {
|
||||
t.setEndBefore(endAncestor);
|
||||
t.collapse(false);
|
||||
}
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
n = endAncestor.previousSibling;
|
||||
while (cnt > 0) {
|
||||
sibling = n.previousSibling;
|
||||
xferNode = t._traverseFullySelected(n, how);
|
||||
|
||||
if (frag)
|
||||
frag.insertBefore(xferNode, frag.firstChild);
|
||||
|
||||
--cnt;
|
||||
n = sibling;
|
||||
}
|
||||
|
||||
// Collapse to just before the endAncestor, which
|
||||
// is partially selected.
|
||||
if (how != CLONE) {
|
||||
t.setEndBefore(endAncestor);
|
||||
t.collapse(false);
|
||||
}
|
||||
|
||||
return frag;
|
||||
},
|
||||
|
||||
_traverseCommonEndContainer : function(startAncestor, how) {
|
||||
var t = this, frag, startIdx, n, cnt, sibling, xferNode;
|
||||
|
||||
if (how != DELETE)
|
||||
frag = t.dom.doc.createDocumentFragment();
|
||||
|
||||
n = t._traverseLeftBoundary(startAncestor, how);
|
||||
if (frag)
|
||||
frag.appendChild(n);
|
||||
|
||||
startIdx = indexOf(startAncestor, t.endContainer);
|
||||
++startIdx; // Because we already traversed it....
|
||||
|
||||
cnt = t.endOffset - startIdx;
|
||||
n = startAncestor.nextSibling;
|
||||
while (cnt > 0) {
|
||||
sibling = n.nextSibling;
|
||||
xferNode = t._traverseFullySelected(n, how);
|
||||
|
||||
if (frag)
|
||||
frag.appendChild(xferNode);
|
||||
|
||||
--cnt;
|
||||
n = sibling;
|
||||
}
|
||||
|
||||
if (how != CLONE) {
|
||||
t.setStartAfter(startAncestor);
|
||||
t.collapse(true);
|
||||
}
|
||||
|
||||
return frag;
|
||||
},
|
||||
|
||||
_traverseCommonAncestors : function(startAncestor, endAncestor, how) {
|
||||
var t = this, n, frag, commonParent, startOffset, endOffset, cnt, sibling, nextSibling;
|
||||
|
||||
if (how != DELETE)
|
||||
frag = t.dom.doc.createDocumentFragment();
|
||||
|
||||
n = t._traverseLeftBoundary(startAncestor, how);
|
||||
if (frag)
|
||||
frag.appendChild(n);
|
||||
|
||||
commonParent = startAncestor.parentNode;
|
||||
startOffset = indexOf(startAncestor, commonParent);
|
||||
endOffset = indexOf(endAncestor, commonParent);
|
||||
++startOffset;
|
||||
|
||||
cnt = endOffset - startOffset;
|
||||
sibling = startAncestor.nextSibling;
|
||||
|
||||
while (cnt > 0) {
|
||||
nextSibling = sibling.nextSibling;
|
||||
n = t._traverseFullySelected(sibling, how);
|
||||
|
||||
if (frag)
|
||||
frag.appendChild(n);
|
||||
|
||||
sibling = nextSibling;
|
||||
--cnt;
|
||||
}
|
||||
|
||||
n = t._traverseRightBoundary(endAncestor, how);
|
||||
|
||||
if (frag)
|
||||
frag.appendChild(n);
|
||||
|
||||
if (how != CLONE) {
|
||||
t.setStartAfter(startAncestor);
|
||||
t.collapse(true);
|
||||
}
|
||||
|
||||
return frag;
|
||||
},
|
||||
|
||||
_traverseRightBoundary : function(root, how) {
|
||||
var t = this, next = getSelectedNode(t.endContainer, t.endOffset - 1), parent, clonedParent, prevSibling, clonedChild, clonedGrandParent;
|
||||
var isFullySelected = next != t.endContainer;
|
||||
|
||||
if (next == root)
|
||||
return t._traverseNode(next, isFullySelected, false, how);
|
||||
|
||||
parent = next.parentNode;
|
||||
clonedParent = t._traverseNode(parent, false, false, how);
|
||||
|
||||
while (parent != null) {
|
||||
while (next != null) {
|
||||
prevSibling = next.previousSibling;
|
||||
clonedChild = t._traverseNode(next, isFullySelected, false, how);
|
||||
|
||||
if (how != DELETE)
|
||||
clonedParent.insertBefore(clonedChild, clonedParent.firstChild);
|
||||
|
||||
isFullySelected = true;
|
||||
next = prevSibling;
|
||||
}
|
||||
|
||||
if (parent == root)
|
||||
return clonedParent;
|
||||
|
||||
next = parent.previousSibling;
|
||||
parent = parent.parentNode;
|
||||
|
||||
clonedGrandParent = t._traverseNode(parent, false, false, how);
|
||||
|
||||
if (how != DELETE)
|
||||
clonedGrandParent.appendChild(clonedParent);
|
||||
|
||||
clonedParent = clonedGrandParent;
|
||||
}
|
||||
|
||||
// should never occur
|
||||
return null;
|
||||
},
|
||||
|
||||
_traverseLeftBoundary : function(root, how) {
|
||||
var t = this, next = getSelectedNode(t.startContainer, t.startOffset);
|
||||
var isFullySelected = next != t.startContainer, parent, clonedParent, nextSibling, clonedChild, clonedGrandParent;
|
||||
|
||||
if (next == root)
|
||||
return t._traverseNode(next, isFullySelected, true, how);
|
||||
|
||||
parent = next.parentNode;
|
||||
clonedParent = t._traverseNode(parent, false, true, how);
|
||||
|
||||
while (parent != null) {
|
||||
while (next != null) {
|
||||
nextSibling = next.nextSibling;
|
||||
clonedChild = t._traverseNode(next, isFullySelected, true, how);
|
||||
|
||||
if (how != DELETE)
|
||||
clonedParent.appendChild(clonedChild);
|
||||
|
||||
isFullySelected = true;
|
||||
next = nextSibling;
|
||||
}
|
||||
|
||||
if (parent == root)
|
||||
return clonedParent;
|
||||
|
||||
next = parent.nextSibling;
|
||||
parent = parent.parentNode;
|
||||
|
||||
clonedGrandParent = t._traverseNode(parent, false, true, how);
|
||||
|
||||
if (how != DELETE)
|
||||
clonedGrandParent.appendChild(clonedParent);
|
||||
|
||||
clonedParent = clonedGrandParent;
|
||||
}
|
||||
|
||||
// should never occur
|
||||
return null;
|
||||
},
|
||||
|
||||
_traverseNode : function(n, isFullySelected, isLeft, how) {
|
||||
var t = this, txtValue, newNodeValue, oldNodeValue, offset, newNode;
|
||||
|
||||
if (isFullySelected)
|
||||
return t._traverseFullySelected(n, how);
|
||||
|
||||
if (n.nodeType == 3 /* TEXT_NODE */) {
|
||||
txtValue = n.nodeValue;
|
||||
|
||||
if (isLeft) {
|
||||
offset = t.startOffset;
|
||||
newNodeValue = txtValue.substring(offset);
|
||||
oldNodeValue = txtValue.substring(0, offset);
|
||||
} else {
|
||||
offset = t.endOffset;
|
||||
newNodeValue = txtValue.substring(0, offset);
|
||||
oldNodeValue = txtValue.substring(offset);
|
||||
}
|
||||
|
||||
if (how != CLONE)
|
||||
n.nodeValue = oldNodeValue;
|
||||
|
||||
if (how == DELETE)
|
||||
return null;
|
||||
|
||||
newNode = n.cloneNode(false);
|
||||
newNode.nodeValue = newNodeValue;
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
if (how == DELETE)
|
||||
return null;
|
||||
|
||||
return n.cloneNode(false);
|
||||
},
|
||||
|
||||
_traverseFullySelected : function(n, how) {
|
||||
var t = this;
|
||||
|
||||
if (how != DELETE)
|
||||
return how == CLONE ? n.cloneNode(true) : n;
|
||||
|
||||
n.parentNode.removeChild(n);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
ns.Range = Range;
|
||||
})(tinymce.dom);
|
||||
+17
-13
@@ -1,23 +1,24 @@
|
||||
/**
|
||||
* $Id: ScriptLoader.js 956 2008-11-04 17:39:21Z spocke $
|
||||
* $Id: ScriptLoader.js 1190 2009-08-12 17:59:29Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var each = tinymce.each, Event = tinymce.dom.Event;
|
||||
|
||||
/**#@+
|
||||
* @class This class handles asynchronous/synchronous loading of JavaScript files it will execute callbacks when
|
||||
/**
|
||||
* This class handles asynchronous/synchronous loading of JavaScript files it will execute callbacks when
|
||||
* various items gets loaded. This class is useful to
|
||||
* @member tinymce.dom.ScriptLoader
|
||||
* @class tinymce.dom.ScriptLoader
|
||||
*/
|
||||
tinymce.create('tinymce.dom.ScriptLoader', {
|
||||
/**
|
||||
* Constructs a new script loaded instance. Check the Wiki for more detailed information for this method.
|
||||
*
|
||||
* @constructor
|
||||
* @method ScriptLoader
|
||||
* @param {Object} s Optional settings object for the ScriptLoaded.
|
||||
*/
|
||||
ScriptLoader : function(s) {
|
||||
@@ -26,13 +27,10 @@
|
||||
this.lookup = {};
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns true/false if a script has been loaded or not.
|
||||
*
|
||||
* @method isDone
|
||||
* @param {String} u URL to check for.
|
||||
*/
|
||||
isDone : function(u) {
|
||||
@@ -43,6 +41,7 @@
|
||||
* Marks a specific script to be loaded. This can be useful if a script got loaded outside
|
||||
* the script loader or to skip it from loading some script.
|
||||
*
|
||||
* @method markDone
|
||||
* @param {string} u Absolute URL to the script to mark as loaded.
|
||||
*/
|
||||
markDone : function(u) {
|
||||
@@ -52,10 +51,11 @@
|
||||
/**
|
||||
* Adds a specific script to the load queue of the script loader.
|
||||
*
|
||||
* @method add
|
||||
* @param {String} u Absolute URL to script to add.
|
||||
* @param {function} cb Optional callback function to execute ones this script gets loaded.
|
||||
* @param {Object} s Optional scope to execute callback in.
|
||||
* @param {bool} pr Optional state to add to top or bottom of load queue. Defaults to bottom.
|
||||
* @param {Boolean} pr Optional state to add to top or bottom of load queue. Defaults to bottom.
|
||||
* @return {object} Load queue object contains, state, url and callback.
|
||||
*/
|
||||
add : function(u, cb, s, pr) {
|
||||
@@ -84,6 +84,7 @@
|
||||
/**
|
||||
* Loads a specific script directly without adding it to the load queue.
|
||||
*
|
||||
* @method load
|
||||
* @param {String} u Absolute URL to script to add.
|
||||
* @param {function} cb Optional callback function to execute ones this script gets loaded.
|
||||
* @param {Object} s Optional scope to execute callback in.
|
||||
@@ -131,6 +132,7 @@
|
||||
/**
|
||||
* Starts the loading of the queue.
|
||||
*
|
||||
* @method loadQueue
|
||||
* @param {function} cb Optional callback to execute when all queued items are loaded.
|
||||
* @param {Object} s Optional scope to execute the callback in.
|
||||
*/
|
||||
@@ -158,6 +160,7 @@
|
||||
/**
|
||||
* Evaluates the specified string inside the global namespace/window scope.
|
||||
*
|
||||
* @method eval
|
||||
* @param {string} Script contents to evaluate.
|
||||
*/
|
||||
eval : function(co) {
|
||||
@@ -178,6 +181,7 @@
|
||||
* Loads the specified queue of files and executes the callback ones they are loaded.
|
||||
* This method is generally not used outside this class but it might be useful in some scenarios.
|
||||
*
|
||||
* @method loadScripts
|
||||
* @param {Array} sc Array of queue items to load.
|
||||
* @param {function} cb Optional callback to execute ones all items are loaded.
|
||||
* @param {Object} s Optional scope to execute callback in.
|
||||
@@ -303,6 +307,8 @@
|
||||
/**
|
||||
* Loads the specified script without adding it to any load queue.
|
||||
*
|
||||
* @static
|
||||
* @method loadScript
|
||||
* @param {string} u URL to dynamically load.
|
||||
* @param {function} cb Callback function to executed on load.
|
||||
*/
|
||||
@@ -342,10 +348,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
|
||||
// Global script loader
|
||||
tinymce.ScriptLoader = new tinymce.dom.ScriptLoader();
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
+112
-46
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
* $Id: Selection.js 906 2008-08-24 16:47:29Z spocke $
|
||||
* $Id: Selection.js 1217 2009-08-28 18:31:42Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
function trimNl(s) {
|
||||
return s.replace(/[\n\r]+/g, '');
|
||||
};
|
||||
@@ -13,16 +13,17 @@
|
||||
// Shorten names
|
||||
var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each;
|
||||
|
||||
/**#@+
|
||||
* @class This class handles text and control selection it's an crossbrowser utility class.
|
||||
/**
|
||||
* This class handles text and control selection it's an crossbrowser utility class.
|
||||
* Consult the TinyMCE Wiki API for more details and examples on how to use this class.
|
||||
* @member tinymce.dom.Selection
|
||||
* @class tinymce.dom.Selection
|
||||
*/
|
||||
tinymce.create('tinymce.dom.Selection', {
|
||||
/**
|
||||
* Constructs a new selection instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method Selection
|
||||
* @param {tinymce.dom.DOMUtils} dom DOMUtils object reference.
|
||||
* @param {Window} win Window to bind the selection object to.
|
||||
* @param {tinymce.dom.Serializer} serializer DOM serialization class to use for getContent.
|
||||
@@ -44,17 +45,18 @@
|
||||
t[e] = new tinymce.util.Dispatcher(t);
|
||||
});
|
||||
|
||||
// No W3C Range support
|
||||
if (!t.win.getSelection)
|
||||
t.tridentSel = new tinymce.dom.TridentSelection(t);
|
||||
|
||||
// Prevent leaks
|
||||
tinymce.addUnload(t.destroy, t);
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the selected contents using the DOM serializer passed in to this class.
|
||||
*
|
||||
* @method getContent
|
||||
* @param {Object} s Optional settings class with for example output format text or html.
|
||||
* @return {String} Selected contents in for example HTML format.
|
||||
*/
|
||||
@@ -100,6 +102,7 @@
|
||||
* with the contents passed in to this function. If there is no selection the contents will be inserted
|
||||
* where the caret is placed in the editor/page.
|
||||
*
|
||||
* @method setContent
|
||||
* @param {String} h HTML contents to set could also be other formats depending on settings.
|
||||
* @param {Object} s Optional settings object with for example data format.
|
||||
*/
|
||||
@@ -132,9 +135,11 @@
|
||||
t.setRng(r);
|
||||
|
||||
// Delete the marker, and hopefully the caret gets placed in the right location
|
||||
d.execCommand('Delete', false, null);
|
||||
// Removed this since it seems to remove in FF and simply deleting it
|
||||
// doesn't seem to affect the caret position in any browser
|
||||
//d.execCommand('Delete', false, null);
|
||||
|
||||
// In case it's still there
|
||||
// Remove the caret position
|
||||
t.dom.remove('__caret');
|
||||
} else {
|
||||
if (r.item) {
|
||||
@@ -154,6 +159,7 @@
|
||||
* Returns the start element of a selection range. If the start is in a text
|
||||
* node the parent element will be returned.
|
||||
*
|
||||
* @method getStart
|
||||
* @return {Element} Start element of selection range.
|
||||
*/
|
||||
getStart : function() {
|
||||
@@ -177,7 +183,7 @@
|
||||
if (e.nodeName == 'BODY')
|
||||
return e.firstChild;
|
||||
|
||||
return t.dom.getParent(e, function(n) {return n.nodeType == 1;});
|
||||
return t.dom.getParent(e, '*');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -185,6 +191,7 @@
|
||||
* Returns the end element of a selection range. If the end is in a text
|
||||
* node the parent element will be returned.
|
||||
*
|
||||
* @method getEnd
|
||||
* @return {Element} End element of selection range.
|
||||
*/
|
||||
getEnd : function() {
|
||||
@@ -208,7 +215,7 @@
|
||||
if (e.nodeName == 'BODY')
|
||||
return e.lastChild;
|
||||
|
||||
return t.dom.getParent(e, function(n) {return n.nodeType == 1;});
|
||||
return t.dom.getParent(e, '*');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -216,7 +223,8 @@
|
||||
* Returns a bookmark location for the current selection. This bookmark object
|
||||
* can then be used to restore the selection after some content modification to the document.
|
||||
*
|
||||
* @param {bool} si Optional state if the bookmark should be simple or not. Default is complex.
|
||||
* @method getBookmark
|
||||
* @param {Boolean} si Optional state if the bookmark should be simple or not. Default is complex.
|
||||
* @return {Object} Bookmark object, use moveToBookmark with this object to restore the selection.
|
||||
*/
|
||||
getBookmark : function(si) {
|
||||
@@ -225,7 +233,7 @@
|
||||
sy = vp.y;
|
||||
|
||||
// Simple bookmark fast but not as persistent
|
||||
if (si == 'simple')
|
||||
if (si)
|
||||
return {rng : r, scrollX : sx, scrollY : sy};
|
||||
|
||||
// Handle IE
|
||||
@@ -346,8 +354,9 @@
|
||||
/**
|
||||
* Restores the selection to the specified bookmark.
|
||||
*
|
||||
* @method moveToBookmark
|
||||
* @param {Object} bookmark Bookmark to restore selection from.
|
||||
* @return {bool} true/false if it was successful or not.
|
||||
* @return {Boolean} true/false if it was successful or not.
|
||||
*/
|
||||
moveToBookmark : function(b) {
|
||||
var t = this, r = t.getRng(), s = t.getSel(), ro = t.dom.getRoot(), sd, nvl, nv;
|
||||
@@ -393,6 +402,8 @@
|
||||
|
||||
// Handle explorer
|
||||
if (isIE) {
|
||||
t.tridentSel.destroy();
|
||||
|
||||
// Handle simple
|
||||
if (r = b.rng) {
|
||||
try {
|
||||
@@ -473,26 +484,32 @@
|
||||
/**
|
||||
* Selects the specified element. This will place the start and end of the selection range around the element.
|
||||
*
|
||||
* @method select
|
||||
* @param {Element} n HMTL DOM element to select.
|
||||
* @param {} c Bool state if the contents should be selected or not on non IE browser.
|
||||
* @param {Boolean} c Bool state if the contents should be selected or not on non IE browser.
|
||||
* @return {Element} Selected element the same element as the one that got passed in.
|
||||
*/
|
||||
select : function(n, c) {
|
||||
var t = this, r = t.getRng(), s = t.getSel(), b, fn, ln, d = t.win.document;
|
||||
|
||||
function first(n) {
|
||||
return n ? d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() : null;
|
||||
};
|
||||
function find(n, start) {
|
||||
var walker, o;
|
||||
|
||||
function last(n) {
|
||||
var c, o, w;
|
||||
if (n) {
|
||||
walker = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);
|
||||
|
||||
if (!n)
|
||||
return null;
|
||||
// Find first/last non empty text node
|
||||
while (n = walker.nextNode()) {
|
||||
o = n;
|
||||
|
||||
w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);
|
||||
while (c = w.nextNode())
|
||||
o = c;
|
||||
if (tinymce.trim(n.nodeValue).length != 0) {
|
||||
if (start)
|
||||
return n;
|
||||
else
|
||||
o = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return o;
|
||||
};
|
||||
@@ -515,14 +532,21 @@
|
||||
}
|
||||
} else {
|
||||
if (c) {
|
||||
fn = first(n);
|
||||
ln = last(n);
|
||||
fn = find(n, 1) || t.dom.select('br:first', n)[0];
|
||||
ln = find(n, 0) || t.dom.select('br:last', n)[0];
|
||||
|
||||
if (fn && ln) {
|
||||
//console.debug(fn, ln);
|
||||
r = d.createRange();
|
||||
r.setStart(fn, 0);
|
||||
r.setEnd(ln, ln.nodeValue.length);
|
||||
|
||||
if (fn.nodeName == 'BR')
|
||||
r.setStartBefore(fn);
|
||||
else
|
||||
r.setStart(fn, 0);
|
||||
|
||||
if (ln.nodeName == 'BR')
|
||||
r.setEndBefore(ln);
|
||||
else
|
||||
r.setEnd(ln, ln.nodeValue.length);
|
||||
} else
|
||||
r.selectNode(n);
|
||||
} else
|
||||
@@ -537,7 +561,8 @@
|
||||
/**
|
||||
* Returns true/false if the selection range is collapsed or not. Collapsed means if it's a caret or a larger selection.
|
||||
*
|
||||
* @return {bool} true/false state if the selection range is collapsed or not. Collapsed means if it's a caret or a larger selection.
|
||||
* @method isCollapsed
|
||||
* @return {Boolean} true/false state if the selection range is collapsed or not. Collapsed means if it's a caret or a larger selection.
|
||||
*/
|
||||
isCollapsed : function() {
|
||||
var t = this, r = t.getRng(), s = t.getSel();
|
||||
@@ -551,7 +576,8 @@
|
||||
/**
|
||||
* Collapse the selection to start or end of range.
|
||||
*
|
||||
* @param {bool} b Optional boolean state if to collapse to end or not. Defaults to start.
|
||||
* @method collapse
|
||||
* @param {Boolean} b Optional boolean state if to collapse to end or not. Defaults to start.
|
||||
*/
|
||||
collapse : function(b) {
|
||||
var t = this, r = t.getRng(), n;
|
||||
@@ -570,6 +596,7 @@
|
||||
/**
|
||||
* Returns the browsers internal selection object.
|
||||
*
|
||||
* @method getSel
|
||||
* @return {Selection} Internal browser selection object.
|
||||
*/
|
||||
getSel : function() {
|
||||
@@ -581,13 +608,19 @@
|
||||
/**
|
||||
* Returns the browsers internal range object.
|
||||
*
|
||||
* @method getRng
|
||||
* @param {Boolean} w3c Forces a compatible W3C range on IE.
|
||||
* @return {Range} Internal browser range object.
|
||||
*/
|
||||
getRng : function() {
|
||||
var t = this, s = t.getSel(), r;
|
||||
getRng : function(w3c) {
|
||||
var t = this, s, r;
|
||||
|
||||
// Found tridentSel object then we need to use that one
|
||||
if (w3c && t.tridentSel)
|
||||
return t.tridentSel.getRangeAt(0);
|
||||
|
||||
try {
|
||||
if (s)
|
||||
if (s = t.getSel())
|
||||
r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : t.win.document.createRange());
|
||||
} catch (ex) {
|
||||
// IE throws unspecified error here if TinyMCE is placed in a frame/iframe
|
||||
@@ -605,19 +638,27 @@
|
||||
/**
|
||||
* Changes the selection to the specified DOM range.
|
||||
*
|
||||
* @method setRng
|
||||
* @param {Range} r Range to select.
|
||||
*/
|
||||
setRng : function(r) {
|
||||
var s;
|
||||
var s, t = this;
|
||||
|
||||
if (!isIE) {
|
||||
s = this.getSel();
|
||||
if (!t.tridentSel) {
|
||||
s = t.getSel();
|
||||
|
||||
if (s) {
|
||||
s.removeAllRanges();
|
||||
s.addRange(r);
|
||||
}
|
||||
} else {
|
||||
// Is W3C Range
|
||||
if (r.cloneRange) {
|
||||
t.tridentSel.addRange(r);
|
||||
return;
|
||||
}
|
||||
|
||||
// Is IE specific range
|
||||
try {
|
||||
r.select();
|
||||
} catch (ex) {
|
||||
@@ -629,6 +670,7 @@
|
||||
/**
|
||||
* Sets the current selection to the specified DOM element.
|
||||
*
|
||||
* @method setNode
|
||||
* @param {Element} n Element to set as the contents of the selection.
|
||||
* @return {Element} Returns the element that got passed in.
|
||||
*/
|
||||
@@ -643,6 +685,7 @@
|
||||
/**
|
||||
* Returns the currently selected element or the common ancestor element for both start and end of the selection.
|
||||
*
|
||||
* @method getNode
|
||||
* @return {Element} Currently selected element or common ancestor element.
|
||||
*/
|
||||
getNode : function() {
|
||||
@@ -669,24 +712,47 @@
|
||||
}
|
||||
}
|
||||
|
||||
return t.dom.getParent(e, function(n) {
|
||||
return n.nodeType == 1;
|
||||
});
|
||||
return t.dom.getParent(e, '*');
|
||||
}
|
||||
|
||||
return r.item ? r.item(0) : r.parentElement();
|
||||
},
|
||||
|
||||
getSelectedBlocks : function(st, en) {
|
||||
var t = this, dom = t.dom, sb, eb, n, bl = [];
|
||||
|
||||
sb = dom.getParent(st || t.getStart(), dom.isBlock);
|
||||
eb = dom.getParent(en || t.getEnd(), dom.isBlock);
|
||||
|
||||
if (sb)
|
||||
bl.push(sb);
|
||||
|
||||
if (sb && eb && sb != eb) {
|
||||
n = sb;
|
||||
|
||||
while ((n = n.nextSibling) && n != eb) {
|
||||
if (dom.isBlock(n))
|
||||
bl.push(n);
|
||||
}
|
||||
}
|
||||
|
||||
if (eb && sb != eb)
|
||||
bl.push(eb);
|
||||
|
||||
return bl;
|
||||
},
|
||||
|
||||
destroy : function(s) {
|
||||
var t = this;
|
||||
|
||||
t.win = null;
|
||||
|
||||
if (t.tridentSel)
|
||||
t.tridentSel.destroy();
|
||||
|
||||
// Manual destroy then remove unload handler
|
||||
if (!s)
|
||||
tinymce.removeUnload(t.destroy);
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
+112
-91
@@ -1,43 +1,29 @@
|
||||
/**
|
||||
* $Id: Serializer.js 952 2008-11-03 17:56:04Z spocke $
|
||||
* $Id: Serializer.js 1232 2009-09-21 19:04:13Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
// Shorten names
|
||||
var extend = tinymce.extend, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, isIE = tinymce.isIE, isGecko = tinymce.isGecko;
|
||||
|
||||
// Returns only attribites that have values not all attributes in IE
|
||||
function getIEAtts(n) {
|
||||
var o = [];
|
||||
|
||||
// Object will throw exception in IE
|
||||
if (n.nodeName == 'OBJECT')
|
||||
return n.attributes;
|
||||
|
||||
n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi, function(a, b) {
|
||||
o.push({specified : 1, nodeName : b});
|
||||
});
|
||||
|
||||
return o;
|
||||
};
|
||||
|
||||
function wildcardToRE(s) {
|
||||
return s.replace(/([?+*])/g, '.$1');
|
||||
};
|
||||
|
||||
/**#@+
|
||||
* @class This class is used to serialize DOM trees into a string.
|
||||
/**
|
||||
* This class is used to serialize DOM trees into a string.
|
||||
* Consult the TinyMCE Wiki API for more details and examples on how to use this class.
|
||||
* @member tinymce.dom.Serializer
|
||||
* @class tinymce.dom.Serializer
|
||||
*/
|
||||
tinymce.create('tinymce.dom.Serializer', {
|
||||
/**
|
||||
* Constucts a new DOM serializer class.
|
||||
*
|
||||
* @constructor
|
||||
* @method Serializer
|
||||
* @param {Object} s Optional name/Value collection of settings for the serializer.
|
||||
*/
|
||||
Serializer : function(s) {
|
||||
@@ -47,16 +33,11 @@
|
||||
t.onPreProcess = new Dispatcher(t);
|
||||
t.onPostProcess = new Dispatcher(t);
|
||||
|
||||
if (tinymce.relaxedDomain && tinymce.isGecko) {
|
||||
// Gecko has a bug where we can't create a new XML document if domain relaxing is used
|
||||
try {
|
||||
t.writer = new tinymce.dom.XMLWriter();
|
||||
} catch (ex) {
|
||||
// IE might throw exception if ActiveX is disabled so we then switch to the slightly slower StringWriter
|
||||
t.writer = new tinymce.dom.StringWriter();
|
||||
} else {
|
||||
try {
|
||||
t.writer = new tinymce.dom.XMLWriter();
|
||||
} catch (ex) {
|
||||
// IE might throw exception if ActiveX is disabled so we then switch to the slightly slower StringWriter
|
||||
t.writer = new tinymce.dom.StringWriter();
|
||||
}
|
||||
}
|
||||
|
||||
// Default settings
|
||||
@@ -65,16 +46,15 @@
|
||||
valid_nodes : 0,
|
||||
node_filter : 0,
|
||||
attr_filter : 0,
|
||||
invalid_attrs : /^(mce_|_moz_)/,
|
||||
closed : /(br|hr|input|meta|img|link|param)/,
|
||||
invalid_attrs : /^(mce_|_moz_|sizset|sizcache)/,
|
||||
closed : /^(br|hr|input|meta|img|link|param|area)$/,
|
||||
entity_encoding : 'named',
|
||||
entities : '160,nbsp,161,iexcl,162,cent,163,pound,164,curren,165,yen,166,brvbar,167,sect,168,uml,169,copy,170,ordf,171,laquo,172,not,173,shy,174,reg,175,macr,176,deg,177,plusmn,178,sup2,179,sup3,180,acute,181,micro,182,para,183,middot,184,cedil,185,sup1,186,ordm,187,raquo,188,frac14,189,frac12,190,frac34,191,iquest,192,Agrave,193,Aacute,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,201,Eacute,202,Ecirc,203,Euml,204,Igrave,205,Iacute,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,211,Oacute,212,Ocirc,213,Otilde,214,Ouml,215,times,216,Oslash,217,Ugrave,218,Uacute,219,Ucirc,220,Uuml,221,Yacute,222,THORN,223,szlig,224,agrave,225,aacute,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,233,eacute,234,ecirc,235,euml,236,igrave,237,iacute,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,243,oacute,244,ocirc,245,otilde,246,ouml,247,divide,248,oslash,249,ugrave,250,uacute,251,ucirc,252,uuml,253,yacute,254,thorn,255,yuml,402,fnof,913,Alpha,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,977,thetasym,978,upsih,982,piv,8226,bull,8230,hellip,8242,prime,8243,Prime,8254,oline,8260,frasl,8472,weierp,8465,image,8476,real,8482,trade,8501,alefsym,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8704,forall,8706,part,8707,exist,8709,empty,8711,nabla,8712,isin,8713,notin,8715,ni,8719,prod,8721,sum,8722,minus,8727,lowast,8730,radic,8733,prop,8734,infin,8736,ang,8743,and,8744,or,8745,cap,8746,cup,8747,int,8756,there4,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8804,le,8805,ge,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,338,OElig,339,oelig,352,Scaron,353,scaron,376,Yuml,710,circ,732,tilde,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,8211,ndash,8212,mdash,8216,lsquo,8217,rsquo,8218,sbquo,8220,ldquo,8221,rdquo,8222,bdquo,8224,dagger,8225,Dagger,8240,permil,8249,lsaquo,8250,rsaquo,8364,euro',
|
||||
bool_attrs : /(checked|disabled|readonly|selected|nowrap)/,
|
||||
valid_elements : '*[*]',
|
||||
extended_valid_elements : 0,
|
||||
valid_child_elements : 0,
|
||||
invalid_elements : 0,
|
||||
fix_table_elements : 0,
|
||||
fix_table_elements : 1,
|
||||
fix_list_elements : true,
|
||||
fix_content_duplication : true,
|
||||
convert_fonts_to_spans : false,
|
||||
@@ -93,8 +73,14 @@
|
||||
|
||||
if (s.remove_redundant_brs) {
|
||||
t.onPostProcess.add(function(se, o) {
|
||||
// Remove BR elements at end of list elements since they get rendered in IE
|
||||
o.content = o.content.replace(/<br \/>(\s*<\/li>)/g, '$1');
|
||||
// Remove single BR at end of block elements since they get rendered
|
||||
o.content = o.content.replace(/(<br \/>\s*)+<\/(p|h[1-6]|div|li)>/gi, function(a, b, c) {
|
||||
// Check if it's a single element
|
||||
if (/^<br \/>\s*<\//.test(a))
|
||||
return '</' + c + '>';
|
||||
|
||||
return a;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -147,53 +133,29 @@
|
||||
|
||||
if (s.fix_table_elements) {
|
||||
t.onPreProcess.add(function(se, o) {
|
||||
each(t.dom.select('table', o.node), function(e) {
|
||||
var pa = t.dom.getParent(e, 'H1,H2,H3,H4,H5,H6,P'), pa2, n, tm, pl = [], i, ns;
|
||||
// Since Opera will crash if you attach the node to a dynamic document we need to brrowser sniff a specific build
|
||||
// so Opera users with an older version will have to live with less compaible output not much we can do here
|
||||
if (!tinymce.isOpera || opera.buildNumber() >= 1767) {
|
||||
each(t.dom.select('p table', o.node).reverse(), function(n) {
|
||||
var parent = t.dom.getParent(n.parentNode, 'table,p');
|
||||
|
||||
if (pa) {
|
||||
pa2 = pa.cloneNode(false);
|
||||
|
||||
pl.push(e);
|
||||
for (n = e; n = n.parentNode;) {
|
||||
pl.push(n);
|
||||
|
||||
if (n == pa)
|
||||
break;
|
||||
}
|
||||
|
||||
tm = pa2;
|
||||
for (i = pl.length - 1; i >= 0; i--) {
|
||||
if (i == pl.length - 1) {
|
||||
while (ns = pl[i - 1].nextSibling)
|
||||
tm.appendChild(ns.parentNode.removeChild(ns));
|
||||
} else {
|
||||
n = pl[i].cloneNode(false);
|
||||
|
||||
if (i != 0) {
|
||||
while (ns = pl[i - 1].nextSibling)
|
||||
n.appendChild(ns.parentNode.removeChild(ns));
|
||||
}
|
||||
|
||||
tm = tm.appendChild(n);
|
||||
if (parent.nodeName != 'TABLE') {
|
||||
try {
|
||||
t.dom.split(parent, n);
|
||||
} catch (ex) {
|
||||
// IE can sometimes fire an unknown runtime error so we just ignore it
|
||||
}
|
||||
}
|
||||
|
||||
e = t.dom.insertAfter(e.parentNode.removeChild(e), pa);
|
||||
t.dom.insertAfter(e, pa);
|
||||
t.dom.insertAfter(pa2, e);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets a list of entities to use for the named entity encoded.
|
||||
*
|
||||
* @method setEntities
|
||||
* @param {String} s List of entities in the following format: number,name,....
|
||||
*/
|
||||
setEntities : function(s) {
|
||||
@@ -231,6 +193,7 @@
|
||||
* Sets the valid child rules. This enables you to specify what elements can be childrens of what parents.
|
||||
* Consult the Wiki for format description on this input.
|
||||
*
|
||||
* @method setValidChildRules
|
||||
* @param {String} s String with valid child rules.
|
||||
*/
|
||||
setValidChildRules : function(s) {
|
||||
@@ -242,6 +205,7 @@
|
||||
* Adds valid child rules. This enables you to specify what elements can be childrens of what parents.
|
||||
* Consult the Wiki for format description on this input.
|
||||
*
|
||||
* @method addValidChildRules
|
||||
* @param {String} s String with valid child rules to add.
|
||||
*/
|
||||
addValidChildRules : function(s) {
|
||||
@@ -320,6 +284,7 @@
|
||||
* outputted and what attributes specific elements might have.
|
||||
* Consult the Wiki for more details on this format.
|
||||
*
|
||||
* @method setRules
|
||||
* @param {String} s Valid elements rules string.
|
||||
*/
|
||||
setRules : function(s) {
|
||||
@@ -338,6 +303,7 @@
|
||||
* outputted and what attributes specific elements might have.
|
||||
* Consult the Wiki for more details on this format.
|
||||
*
|
||||
* @method addRules
|
||||
* @param {String} s Valid elements rules string to add.
|
||||
*/
|
||||
addRules : function(s) {
|
||||
@@ -504,6 +470,7 @@
|
||||
/**
|
||||
* Finds a rule object by name.
|
||||
*
|
||||
* @method findRule
|
||||
* @param {String} n Name to look for in rules collection.
|
||||
* @return {Object} Rule object found or null if it wasn't found.
|
||||
*/
|
||||
@@ -530,6 +497,7 @@
|
||||
/**
|
||||
* Finds an attribute rule object by name.
|
||||
*
|
||||
* @method findAttribRule
|
||||
* @param {Object} ru Rule object to search though.
|
||||
* @param {String} n Name of the rule to retrive.
|
||||
* @return {Object} Rule object of the specified attribute.
|
||||
@@ -548,18 +516,64 @@
|
||||
/**
|
||||
* Serializes the specified node into a HTML string.
|
||||
*
|
||||
* @method serialize
|
||||
* @param {Element} n Element/Node to serialize.
|
||||
* @param {Object} o Object to add serialized contents to, this object will also be passed to the event listeners.
|
||||
* @return {String} Serialized HTML contents.
|
||||
*/
|
||||
serialize : function(n, o) {
|
||||
var h, t = this;
|
||||
var h, t = this, doc, oldDoc, impl, selected;
|
||||
|
||||
t._setup();
|
||||
o = o || {};
|
||||
o.format = o.format || 'html';
|
||||
t.processObj = o;
|
||||
|
||||
// IE looses the selected attribute on option elements so we need to store it
|
||||
// See: http://support.microsoft.com/kb/829907
|
||||
if (isIE) {
|
||||
selected = [];
|
||||
each(n.getElementsByTagName('option'), function(n) {
|
||||
var v = t.dom.getAttrib(n, 'selected');
|
||||
|
||||
selected.push(v ? v : null);
|
||||
});
|
||||
}
|
||||
|
||||
n = n.cloneNode(true);
|
||||
|
||||
// IE looses the selected attribute on option elements so we need to restore it
|
||||
if (isIE) {
|
||||
each(n.getElementsByTagName('option'), function(n, i) {
|
||||
t.dom.setAttrib(n, 'selected', selected[i]);
|
||||
});
|
||||
}
|
||||
|
||||
// Nodes needs to be attached to something in WebKit/Opera
|
||||
// Older builds of Opera crashes if you attach the node to an document created dynamically
|
||||
// and since we can't feature detect a crash we need to sniff the acutal build number
|
||||
// This fix will make DOM ranges and make Sizzle happy!
|
||||
impl = n.ownerDocument.implementation;
|
||||
if (impl.createHTMLDocument && (tinymce.isOpera && opera.buildNumber() >= 1767)) {
|
||||
// Create an empty HTML document
|
||||
doc = impl.createHTMLDocument("");
|
||||
|
||||
// Add the element or it's children if it's a body element to the new document
|
||||
each(n.nodeName == 'BODY' ? n.childNodes : [n], function(node) {
|
||||
doc.body.appendChild(doc.importNode(node, true));
|
||||
});
|
||||
|
||||
// Grab first child or body element for serialization
|
||||
if (n.nodeName != 'BODY')
|
||||
n = doc.body.firstChild;
|
||||
else
|
||||
n = doc.body;
|
||||
|
||||
// set the new document in DOMUtils so createElement etc works
|
||||
oldDoc = t.dom.doc;
|
||||
t.dom.doc = doc;
|
||||
}
|
||||
|
||||
t.key = '' + (parseInt(t.key) + 1);
|
||||
|
||||
// Pre process
|
||||
@@ -575,6 +589,10 @@
|
||||
// Post process
|
||||
o.content = t.writer.getContent();
|
||||
|
||||
// Restore the old document if it was changed
|
||||
if (oldDoc)
|
||||
t.dom.doc = oldDoc;
|
||||
|
||||
if (!o.no_events)
|
||||
t.onPostProcess.dispatch(t, o);
|
||||
|
||||
@@ -600,6 +618,7 @@
|
||||
content : h,
|
||||
patterns : [
|
||||
{pattern : /(<script[^>]*>)(.*?)(<\/script>)/g},
|
||||
{pattern : /(<noscript[^>]*>)(.*?)(<\/noscript>)/g},
|
||||
{pattern : /(<style[^>]*>)(.*?)(<\/style>)/g},
|
||||
{pattern : /(<pre[^>]*>)(.*?)(<\/pre>)/g, encode : 1},
|
||||
{pattern : /(<!--\[CDATA\[)(.*?)(\]\]-->)/g}
|
||||
@@ -652,13 +671,18 @@
|
||||
// Restore the \u00a0 character if raw mode is enabled
|
||||
if (s.entity_encoding == 'raw')
|
||||
h = h.replace(/<p> <\/p>|<p([^>]+)> <\/p>/g, '<p$1>\u00a0</p>');
|
||||
|
||||
// Restore noscript elements
|
||||
h = h.replace(/<noscript([^>]+|)>([\s\S]*?)<\/noscript>/g, function(v, attribs, text) {
|
||||
return '<noscript' + attribs + '>' + t.dom.decode(text.replace(/<!--|-->/g, '')) + '</noscript>';
|
||||
});
|
||||
}
|
||||
|
||||
o.content = h;
|
||||
},
|
||||
|
||||
_serializeNode : function(n, inn) {
|
||||
var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv;
|
||||
var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv, closed;
|
||||
|
||||
if (!s.node_filter || s.node_filter(n)) {
|
||||
switch (n.nodeType) {
|
||||
@@ -681,7 +705,7 @@
|
||||
nn = nn.substring(4);
|
||||
|
||||
// Check if valid
|
||||
if (!t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inn) {
|
||||
if (!t.validElementsRE || !t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inn) {
|
||||
iv = true;
|
||||
break;
|
||||
}
|
||||
@@ -718,6 +742,7 @@
|
||||
|
||||
ru = t.findRule(nn);
|
||||
nn = ru.name || nn;
|
||||
closed = s.closed.test(nn);
|
||||
|
||||
// Skip empty nodes or empty node name in IE
|
||||
if ((!hc && ru.noEmpty) || (isIE && !nn)) {
|
||||
@@ -756,7 +781,7 @@
|
||||
|
||||
// Add wild attributes
|
||||
if (ru.validAttribsRE) {
|
||||
at = isIE ? getIEAtts(n) : n.attributes;
|
||||
at = t.dom.getAttribs(n);
|
||||
for (i=at.length-1; i>-1; i--) {
|
||||
no = at[i];
|
||||
|
||||
@@ -775,6 +800,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Write text from script
|
||||
if (nn === 'script' && tinymce.trim(n.innerHTML)) {
|
||||
w.writeText('// '); // Padd it with a comment so it will parse on older browsers
|
||||
w.writeCDATA(n.innerHTML.replace(/<!--|-->|<\[CDATA\[|\]\]>/g, '')); // Remove comments and cdata stuctures
|
||||
hc = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Padd empty nodes with a
|
||||
if (ru.padd) {
|
||||
// If it has only one bogus child, padd it anyway workaround for <td><br /></td> bug
|
||||
@@ -805,7 +838,7 @@
|
||||
} else if (n.nodeType == 1)
|
||||
hc = n.hasChildNodes();
|
||||
|
||||
if (hc) {
|
||||
if (hc && !closed) {
|
||||
cn = n.firstChild;
|
||||
|
||||
while (cn) {
|
||||
@@ -817,7 +850,7 @@
|
||||
|
||||
// Write element end
|
||||
if (!iv) {
|
||||
if (hc || !s.closed.test(nn))
|
||||
if (!closed)
|
||||
w.writeFullEndElement();
|
||||
else
|
||||
w.writeEndElement();
|
||||
@@ -938,16 +971,6 @@
|
||||
|
||||
v = this.dom.getAttrib(n, na);
|
||||
|
||||
// Bool attr
|
||||
if (this.settings.bool_attrs.test(na) && v) {
|
||||
v = ('' + v).toLowerCase();
|
||||
|
||||
if (v === 'false' || v === '0')
|
||||
return null;
|
||||
|
||||
v = na;
|
||||
}
|
||||
|
||||
switch (na) {
|
||||
case 'rowspan':
|
||||
case 'colspan':
|
||||
@@ -990,7 +1013,5 @@
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
+626
-327
File diff suppressed because it is too large
Load Diff
+22
-13
@@ -1,14 +1,14 @@
|
||||
/**
|
||||
* $Id: StringWriter.js 602 2008-02-15 14:52:29Z spocke $
|
||||
* $Id: StringWriter.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
/**#@+
|
||||
* @class This class writes nodes into a string.
|
||||
* @member tinymce.dom.StringWriter
|
||||
(function(tinymce) {
|
||||
/**
|
||||
* This class writes nodes into a string.
|
||||
* @class tinymce.dom.StringWriter
|
||||
*/
|
||||
tinymce.create('tinymce.dom.StringWriter', {
|
||||
str : null,
|
||||
@@ -21,23 +21,22 @@
|
||||
* Constructs a new StringWriter.
|
||||
*
|
||||
* @constructor
|
||||
* @method StringWriter
|
||||
* @param {Object} s Optional settings object.
|
||||
*/
|
||||
StringWriter : function(s) {
|
||||
this.settings = tinymce.extend({
|
||||
indent_char : ' ',
|
||||
indentation : 1
|
||||
indentation : 0
|
||||
}, s);
|
||||
|
||||
this.reset();
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resets the writer so it can be reused the contents of the writer is cleared.
|
||||
*
|
||||
* @method reset
|
||||
*/
|
||||
reset : function() {
|
||||
this.indent = '';
|
||||
@@ -49,6 +48,7 @@
|
||||
/**
|
||||
* Writes the start of an element like for example: <tag.
|
||||
*
|
||||
* @method writeStartElement
|
||||
* @param {String} n Name of element to write.
|
||||
*/
|
||||
writeStartElement : function(n) {
|
||||
@@ -63,6 +63,7 @@
|
||||
/**
|
||||
* Writes an attrubute like for example: myattr="valie"
|
||||
*
|
||||
* @method writeAttribute
|
||||
* @param {String} n Attribute name to write.
|
||||
* @param {String} v Attribute value to write.
|
||||
*/
|
||||
@@ -74,6 +75,8 @@
|
||||
|
||||
/**
|
||||
* Write the end of a element. This will add a short end for elements with out children like for example a img element.
|
||||
*
|
||||
* @method writeEndElement
|
||||
*/
|
||||
writeEndElement : function() {
|
||||
var n;
|
||||
@@ -91,6 +94,8 @@
|
||||
|
||||
/**
|
||||
* Writes the end of a element. This will add a full end to the element even if it didn't have any children.
|
||||
*
|
||||
* @method writeFullEndElement
|
||||
*/
|
||||
writeFullEndElement : function() {
|
||||
if (this.tags.length > 0) {
|
||||
@@ -105,6 +110,7 @@
|
||||
/**
|
||||
* Writes a text node value.
|
||||
*
|
||||
* @method writeText
|
||||
* @param {String} v Value to append as a text node.
|
||||
*/
|
||||
writeText : function(v) {
|
||||
@@ -116,6 +122,7 @@
|
||||
/**
|
||||
* Writes a CDATA section.
|
||||
*
|
||||
* @method writeCDATA
|
||||
* @param {String} v Value to write in CDATA.
|
||||
*/
|
||||
writeCDATA : function(v) {
|
||||
@@ -127,6 +134,7 @@
|
||||
/**
|
||||
* Writes a comment.
|
||||
*
|
||||
* @method writeComment
|
||||
* @param {String} v Value of the comment.
|
||||
*/
|
||||
writeComment : function(v) {
|
||||
@@ -138,6 +146,7 @@
|
||||
/**
|
||||
* String writer specific function. Enables you to write raw contents to the string.
|
||||
*
|
||||
* @method writeRaw
|
||||
* @param {String} v String with raw contents to write.
|
||||
*/
|
||||
writeRaw : function(v) {
|
||||
@@ -147,6 +156,7 @@
|
||||
/**
|
||||
* String writer specific method. This encodes the raw entities of a string.
|
||||
*
|
||||
* @method encode
|
||||
* @param {String} s String to encode.
|
||||
* @return {String} String with entity encoding of the raw elements like <>&".
|
||||
*/
|
||||
@@ -173,6 +183,7 @@
|
||||
/**
|
||||
* Returns a string representation of the elements/nodes written.
|
||||
*
|
||||
* @method getContent
|
||||
* @return {String} String representation of the written elements/nodes.
|
||||
*/
|
||||
getContent : function() {
|
||||
@@ -194,7 +205,5 @@
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
/**
|
||||
* $Id: TridentSelection.js 1217 2009-08-28 18:31:42Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
function Selection(selection) {
|
||||
var t = this, invisibleChar = '\uFEFF', range, lastIERng;
|
||||
|
||||
function compareRanges(rng1, rng2) {
|
||||
if (rng1 && rng2) {
|
||||
// Both are control ranges and the selected element matches
|
||||
if (rng1.item && rng2.item && rng1.item(0) === rng2.item(0))
|
||||
return 1;
|
||||
|
||||
// Both are text ranges and the range matches
|
||||
if (rng1.isEqual && rng2.isEqual && rng2.isEqual(rng1))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
function getRange() {
|
||||
var dom = selection.dom, ieRange = selection.getRng(), domRange = dom.createRng(), startPos, endPos, element, sc, ec, collapsed;
|
||||
|
||||
function findIndex(element) {
|
||||
var nl = element.parentNode.childNodes, i;
|
||||
|
||||
for (i = nl.length - 1; i >= 0; i--) {
|
||||
if (nl[i] == element)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
function findEndPoint(start) {
|
||||
var rng = ieRange.duplicate(), parent, i, nl, n, offset = 0, index = 0, pos, tmpRng;
|
||||
|
||||
// Insert marker character
|
||||
rng.collapse(start);
|
||||
parent = rng.parentElement();
|
||||
rng.pasteHTML(invisibleChar); // Needs to be a pasteHTML instead of .text = since IE has a bug with nodeValue
|
||||
|
||||
// Find marker character
|
||||
nl = parent.childNodes;
|
||||
for (i = 0; i < nl.length; i++) {
|
||||
n = nl[i];
|
||||
|
||||
// Calculate node index excluding text node fragmentation
|
||||
if (i > 0 && (n.nodeType !== 3 || nl[i - 1].nodeType !== 3))
|
||||
index++;
|
||||
|
||||
// If text node then calculate offset
|
||||
if (n.nodeType === 3) {
|
||||
// Look for marker
|
||||
pos = n.nodeValue.indexOf(invisibleChar);
|
||||
if (pos !== -1) {
|
||||
offset += pos;
|
||||
break;
|
||||
}
|
||||
|
||||
offset += n.nodeValue.length;
|
||||
} else
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
// Remove marker character
|
||||
rng.moveStart('character', -1);
|
||||
rng.text = '';
|
||||
|
||||
return {index : index, offset : offset, parent : parent};
|
||||
};
|
||||
|
||||
// If selection is outside the current document just return an empty range
|
||||
element = ieRange.item ? ieRange.item(0) : ieRange.parentElement();
|
||||
if (element.ownerDocument != dom.doc)
|
||||
return domRange;
|
||||
|
||||
// Handle control selection or text selection of a image
|
||||
if (ieRange.item || !element.hasChildNodes()) {
|
||||
domRange.setStart(element.parentNode, findIndex(element));
|
||||
domRange.setEnd(domRange.startContainer, domRange.startOffset + 1);
|
||||
|
||||
return domRange;
|
||||
}
|
||||
|
||||
// Check collapsed state
|
||||
collapsed = selection.isCollapsed();
|
||||
|
||||
// Find start and end pos index and offset
|
||||
startPos = findEndPoint(true);
|
||||
endPos = findEndPoint(false);
|
||||
|
||||
// Normalize the elements to avoid fragmented dom
|
||||
startPos.parent.normalize();
|
||||
endPos.parent.normalize();
|
||||
|
||||
// Set start container and offset
|
||||
sc = startPos.parent.childNodes[Math.min(startPos.index, startPos.parent.childNodes.length - 1)];
|
||||
|
||||
if (sc.nodeType != 3)
|
||||
domRange.setStart(startPos.parent, startPos.index);
|
||||
else
|
||||
domRange.setStart(startPos.parent.childNodes[startPos.index], startPos.offset);
|
||||
|
||||
// Set end container and offset
|
||||
ec = endPos.parent.childNodes[Math.min(endPos.index, endPos.parent.childNodes.length - 1)];
|
||||
|
||||
if (ec.nodeType != 3) {
|
||||
if (!collapsed)
|
||||
endPos.index++;
|
||||
|
||||
domRange.setEnd(endPos.parent, endPos.index);
|
||||
} else
|
||||
domRange.setEnd(endPos.parent.childNodes[endPos.index], endPos.offset);
|
||||
|
||||
// If not collapsed then make sure offsets are valid
|
||||
if (!collapsed) {
|
||||
sc = domRange.startContainer;
|
||||
if (sc.nodeType == 1)
|
||||
domRange.setStart(sc, Math.min(domRange.startOffset, sc.childNodes.length));
|
||||
|
||||
ec = domRange.endContainer;
|
||||
if (ec.nodeType == 1)
|
||||
domRange.setEnd(ec, Math.min(domRange.endOffset, ec.childNodes.length));
|
||||
}
|
||||
|
||||
// Restore selection to new range
|
||||
t.addRange(domRange);
|
||||
|
||||
return domRange;
|
||||
};
|
||||
|
||||
this.addRange = function(rng) {
|
||||
var ieRng, body = selection.dom.doc.body, startPos, endPos, sc, so, ec, eo;
|
||||
|
||||
// Setup some shorter versions
|
||||
sc = rng.startContainer;
|
||||
so = rng.startOffset;
|
||||
ec = rng.endContainer;
|
||||
eo = rng.endOffset;
|
||||
ieRng = body.createTextRange();
|
||||
|
||||
// Find element
|
||||
sc = sc.nodeType == 1 ? sc.childNodes[Math.min(so, sc.childNodes.length - 1)] : sc;
|
||||
ec = ec.nodeType == 1 ? ec.childNodes[Math.min(so == eo ? eo : eo - 1, ec.childNodes.length - 1)] : ec;
|
||||
|
||||
// Single element selection
|
||||
if (sc == ec && sc.nodeType == 1) {
|
||||
// Make control selection for some elements
|
||||
if (/^(IMG|TABLE)$/.test(sc.nodeName) && so != eo) {
|
||||
ieRng = body.createControlRange();
|
||||
ieRng.addElement(sc);
|
||||
} else {
|
||||
ieRng = body.createTextRange();
|
||||
|
||||
// Padd empty elements with invisible character
|
||||
if (!sc.hasChildNodes() && sc.canHaveHTML)
|
||||
sc.innerHTML = invisibleChar;
|
||||
|
||||
// Select element contents
|
||||
ieRng.moveToElementText(sc);
|
||||
|
||||
// If it's only containing a padding remove it so the caret remains
|
||||
if (sc.innerHTML == invisibleChar) {
|
||||
ieRng.collapse(true);
|
||||
sc.removeChild(sc.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
if (so == eo)
|
||||
ieRng.collapse(eo <= rng.endContainer.childNodes.length - 1);
|
||||
|
||||
ieRng.select();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
function getCharPos(container, offset) {
|
||||
var nodeVal, rng, pos;
|
||||
|
||||
if (container.nodeType != 3)
|
||||
return -1;
|
||||
|
||||
nodeVal = container.nodeValue;
|
||||
rng = body.createTextRange();
|
||||
|
||||
// Insert marker at offset position
|
||||
container.nodeValue = nodeVal.substring(0, offset) + invisibleChar + nodeVal.substring(offset);
|
||||
|
||||
// Find char pos of marker and remove it
|
||||
rng.moveToElementText(container.parentNode);
|
||||
rng.findText(invisibleChar);
|
||||
pos = Math.abs(rng.moveStart('character', -0xFFFFF));
|
||||
container.nodeValue = nodeVal;
|
||||
|
||||
return pos;
|
||||
};
|
||||
|
||||
// Collapsed range
|
||||
if (rng.collapsed) {
|
||||
pos = getCharPos(sc, so);
|
||||
|
||||
ieRng = body.createTextRange();
|
||||
ieRng.move('character', pos);
|
||||
ieRng.select();
|
||||
|
||||
return;
|
||||
} else {
|
||||
// If same text container
|
||||
if (sc == ec && sc.nodeType == 3) {
|
||||
startPos = getCharPos(sc, so);
|
||||
|
||||
ieRng = body.createTextRange();
|
||||
ieRng.move('character', startPos);
|
||||
ieRng.moveEnd('character', eo - so);
|
||||
ieRng.select();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get caret positions
|
||||
startPos = getCharPos(sc, so);
|
||||
endPos = getCharPos(ec, eo);
|
||||
ieRng = body.createTextRange();
|
||||
|
||||
// Move start of range to start character position or start element
|
||||
if (startPos == -1) {
|
||||
ieRng.moveToElementText(sc);
|
||||
startPos = 0;
|
||||
} else
|
||||
ieRng.move('character', startPos);
|
||||
|
||||
// Move end of range to end character position or end element
|
||||
tmpRng = body.createTextRange();
|
||||
|
||||
if (endPos == -1)
|
||||
tmpRng.moveToElementText(ec);
|
||||
else
|
||||
tmpRng.move('character', endPos);
|
||||
|
||||
ieRng.setEndPoint('EndToEnd', tmpRng);
|
||||
ieRng.select();
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
this.getRangeAt = function() {
|
||||
// Setup new range if the cache is empty
|
||||
if (!range || !compareRanges(lastIERng, selection.getRng())) {
|
||||
range = getRange();
|
||||
|
||||
// Store away text range for next call
|
||||
lastIERng = selection.getRng();
|
||||
}
|
||||
|
||||
// Return cached range
|
||||
return range;
|
||||
};
|
||||
|
||||
this.destroy = function() {
|
||||
// Destroy cached range and last IE range to avoid memory leaks
|
||||
lastIERng = range = null;
|
||||
};
|
||||
};
|
||||
|
||||
// Expose the selection object
|
||||
tinymce.dom.TridentSelection = Selection;
|
||||
})();
|
||||
+20
-13
@@ -1,15 +1,15 @@
|
||||
/**
|
||||
* $Id: XMLWriter.js 906 2008-08-24 16:47:29Z spocke $
|
||||
* $Id: XMLWriter.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
/**#@+
|
||||
* @class This class writes nodes into a XML document structure. This structure can then be
|
||||
(function(tinymce) {
|
||||
/**
|
||||
* This class writes nodes into a XML document structure. This structure can then be
|
||||
* serialized down to a HTML string later on.
|
||||
* @member tinymce.dom.XMLWriter
|
||||
* @class tinymce.dom.XMLWriter
|
||||
*/
|
||||
tinymce.create('tinymce.dom.XMLWriter', {
|
||||
node : null,
|
||||
@@ -18,6 +18,7 @@
|
||||
* Constructs a new XMLWriter.
|
||||
*
|
||||
* @constructor
|
||||
* @method XMLWriter
|
||||
* @param {Object} s Optional settings object.
|
||||
*/
|
||||
XMLWriter : function(s) {
|
||||
@@ -41,12 +42,10 @@
|
||||
this.reset();
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resets the writer so it can be reused the contents of the writer is cleared.
|
||||
*
|
||||
* @method reset
|
||||
*/
|
||||
reset : function() {
|
||||
var t = this, d = t.doc;
|
||||
@@ -60,6 +59,7 @@
|
||||
/**
|
||||
* Writes the start of an element like for example: <tag.
|
||||
*
|
||||
* @method writeStartElement
|
||||
* @param {String} n Name of element to write.
|
||||
*/
|
||||
writeStartElement : function(n) {
|
||||
@@ -71,6 +71,7 @@
|
||||
/**
|
||||
* Writes an attrubute like for example: myattr="valie"
|
||||
*
|
||||
* @method writeAttribute
|
||||
* @param {String} n Attribute name to write.
|
||||
* @param {String} v Attribute value to write.
|
||||
*/
|
||||
@@ -83,6 +84,8 @@
|
||||
|
||||
/**
|
||||
* Write the end of a element. This will add a short end for elements with out children like for example a img element.
|
||||
*
|
||||
* @method writeEndElement
|
||||
*/
|
||||
writeEndElement : function() {
|
||||
this.node = this.node.parentNode;
|
||||
@@ -90,6 +93,8 @@
|
||||
|
||||
/**
|
||||
* Writes the end of a element. This will add a full end to the element even if it didn't have any children.
|
||||
*
|
||||
* @method writeFullEndElement
|
||||
*/
|
||||
writeFullEndElement : function() {
|
||||
var t = this, n = t.node;
|
||||
@@ -101,6 +106,7 @@
|
||||
/**
|
||||
* Writes a text node value.
|
||||
*
|
||||
* @method writeText
|
||||
* @param {String} v Value to append as a text node.
|
||||
*/
|
||||
writeText : function(v) {
|
||||
@@ -113,15 +119,17 @@
|
||||
/**
|
||||
* Writes a CDATA section.
|
||||
*
|
||||
* @method writeCDATA
|
||||
* @param {String} v Value to write in CDATA.
|
||||
*/
|
||||
writeCDATA : function(v) {
|
||||
this.node.appendChild(this.doc.createCDATA(v));
|
||||
this.node.appendChild(this.doc.createCDATASection(v));
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes a comment.
|
||||
*
|
||||
* @method writeComment
|
||||
* @param {String} v Value of the comment.
|
||||
*/
|
||||
writeComment : function(v) {
|
||||
@@ -135,6 +143,7 @@
|
||||
/**
|
||||
* Returns a string representation of the elements/nodes written.
|
||||
*
|
||||
* @method getContent
|
||||
* @return {String} String representation of the written elements/nodes.
|
||||
*/
|
||||
getContent : function() {
|
||||
@@ -149,7 +158,5 @@
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
+2511
-994
File diff suppressed because it is too large
Load Diff
+109
-27
@@ -1,23 +1,29 @@
|
||||
/**
|
||||
* $Id: tinymce.js 966 2008-11-27 17:26:57Z spocke $
|
||||
* $Id: tinymce.js 1200 2009-08-18 12:32:02Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* @class Core namespace with core functionality for the TinyMCE API all sub classes will be added to this namespace/object.
|
||||
/**
|
||||
* Core namespace with core functionality for the TinyMCE API all sub classes will be added to this namespace/object.
|
||||
*
|
||||
* @static
|
||||
* @member tinymce
|
||||
* @class tinymce
|
||||
* @example
|
||||
* // Using each method
|
||||
* tinymce.each([1, 2, 3], function(v, i) {
|
||||
* console.log(i + '=' + v);
|
||||
* });
|
||||
*
|
||||
* // Checking for a specific browser
|
||||
* if (tinymce.isIE)
|
||||
* console.log("IE");
|
||||
*/
|
||||
var tinymce = {
|
||||
majorVersion : '3',
|
||||
minorVersion : '2.1.1',
|
||||
releaseDate : '2008-11-27',
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
majorVersion : '@@tinymce_major_version@@',
|
||||
minorVersion : '@@tinymce_minor_version@@',
|
||||
releaseDate : '@@tinymce_release_date@@',
|
||||
|
||||
/**
|
||||
* Initializes the TinyMCE global namespace this will setup browser detection and figure out where TinyMCE is running from.
|
||||
@@ -25,14 +31,67 @@ var tinymce = {
|
||||
_init : function() {
|
||||
var t = this, d = document, w = window, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
|
||||
|
||||
// Browser checks
|
||||
/**
|
||||
* Constant that is true if the browser is Opera.
|
||||
*
|
||||
* @property isOpera
|
||||
* @type Boolean
|
||||
* @final
|
||||
*/
|
||||
t.isOpera = w.opera && opera.buildNumber;
|
||||
|
||||
/**
|
||||
* Constant that is true if the browser is WebKit (Safari/Chrome).
|
||||
*
|
||||
* @property isWebKit
|
||||
* @type Boolean
|
||||
* @final
|
||||
*/
|
||||
t.isWebKit = /WebKit/.test(ua);
|
||||
t.isOldWebKit = t.isWebKit && !w.getSelection().getRangeAt;
|
||||
|
||||
/**
|
||||
* Constant that is true if the browser is IE.
|
||||
*
|
||||
* @property isIE
|
||||
* @type Boolean
|
||||
* @final
|
||||
*/
|
||||
t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(na.appName);
|
||||
|
||||
/**
|
||||
* Constant that is true if the browser is IE 6 or older.
|
||||
*
|
||||
* @property isIE6
|
||||
* @type Boolean
|
||||
* @final
|
||||
*/
|
||||
t.isIE6 = t.isIE && /MSIE [56]/.test(ua);
|
||||
|
||||
/**
|
||||
* Constant that is true if the browser is Gecko.
|
||||
*
|
||||
* @property isGecko
|
||||
* @type Boolean
|
||||
* @final
|
||||
*/
|
||||
t.isGecko = !t.isWebKit && /Gecko/.test(ua);
|
||||
|
||||
/**
|
||||
* Constant that is true if the os is Mac OS.
|
||||
*
|
||||
* @property isMac
|
||||
* @type Boolean
|
||||
* @final
|
||||
*/
|
||||
t.isMac = ua.indexOf('Mac') != -1;
|
||||
|
||||
/**
|
||||
* Constant that is true if the runtime is Adobe Air.
|
||||
*
|
||||
* @property isAir
|
||||
* @type Boolean
|
||||
* @final
|
||||
*/
|
||||
t.isAir = /adobeair/i.test(ua);
|
||||
|
||||
// TinyMCE .NET webcontrol might be setting the values for TinyMCE
|
||||
@@ -59,7 +118,7 @@ var tinymce = {
|
||||
}
|
||||
|
||||
function getBase(n) {
|
||||
if (n.src && /tiny_mce(|_dev|_src|_gzip|_jquery|_prototype).js/.test(n.src)) {
|
||||
if (n.src && /tiny_mce(|_gzip|_jquery|_prototype)(_dev|_src)?.js/.test(n.src)) {
|
||||
if (/_(src|dev)\.js/g.test(n.src))
|
||||
t.suffix = '_src';
|
||||
|
||||
@@ -69,7 +128,9 @@ var tinymce = {
|
||||
t.baseURL = n.src.substring(0, n.src.lastIndexOf('/'));
|
||||
|
||||
// If path to script is relative and a base href was found add that one infront
|
||||
if (base && t.baseURL.indexOf('://') == -1)
|
||||
// the src property will always be an absolute one on non IE browsers and IE 8
|
||||
// so this logic will basically only be executed on older IE versions
|
||||
if (base && t.baseURL.indexOf('://') == -1 && t.baseURL.indexOf('/') !== 0)
|
||||
t.baseURL = base + t.baseURL;
|
||||
|
||||
return t.baseURL;
|
||||
@@ -101,9 +162,10 @@ var tinymce = {
|
||||
/**
|
||||
* Checks if a object is of a specific type for example an array.
|
||||
*
|
||||
* @method is
|
||||
* @param {Object} o Object to check type of.
|
||||
* @param {string} t Optional type to check for.
|
||||
* @return {bool} true/false if the object is of the specified type.
|
||||
* @return {Boolean} true/false if the object is of the specified type.
|
||||
*/
|
||||
is : function(o, t) {
|
||||
var n = typeof(o);
|
||||
@@ -111,22 +173,25 @@ var tinymce = {
|
||||
if (!t)
|
||||
return n != 'undefined';
|
||||
|
||||
if (t == 'array' && (o instanceof Array))
|
||||
if (t == 'array' && (o.hasOwnProperty && o instanceof Array))
|
||||
return true;
|
||||
|
||||
return n == t;
|
||||
},
|
||||
|
||||
// #if !jquery
|
||||
|
||||
/**
|
||||
* Performs an iteration of all items in a collection such as an object or array. This method will execure the
|
||||
* callback function for each item in the collection, if the callback returns false the iteration will terminate.
|
||||
* The callback has the following format: cb(value, key_or_index).
|
||||
*
|
||||
* @method each
|
||||
* @param {Object} o Collection to iterate.
|
||||
* @param {function} cb Callback function to execute for each item.
|
||||
* @param {Object} s Optional scope to execute the callback in.
|
||||
* @example
|
||||
* tinymce.each([1, 2, 3], function(v, i) {
|
||||
* console.log(i + '=' + v);
|
||||
* });
|
||||
*/
|
||||
each : function(o, cb, s) {
|
||||
var n, l;
|
||||
@@ -155,10 +220,13 @@ var tinymce = {
|
||||
return 1;
|
||||
},
|
||||
|
||||
// #ifndef jquery
|
||||
|
||||
/**
|
||||
* Creates a new array by the return value of each iteration function call. This enables you to convert
|
||||
* one array list into another.
|
||||
*
|
||||
* @method map
|
||||
* @param {Array} a Array of items to iterate.
|
||||
* @param {function} f Function to call for each item. It's return value will be the new value.
|
||||
* @return {Array} Array with new values based on function return values.
|
||||
@@ -177,6 +245,7 @@ var tinymce = {
|
||||
* Filters out items from the input array by calling the specified function for each item.
|
||||
* If the function returns false the item will be excluded if it returns true it will be included.
|
||||
*
|
||||
* @method grep
|
||||
* @param {Array} a Array of items to loop though.
|
||||
* @param {function} f Function to call for each item. Include/exclude depends on it's return value.
|
||||
* @return {Array} New array with values imported and filtered based in input.
|
||||
@@ -195,6 +264,7 @@ var tinymce = {
|
||||
/**
|
||||
* Returns the index of a value in an array, this method will return -1 if the item wasn't found.
|
||||
*
|
||||
* @method inArray
|
||||
* @param {Array} a Array/Object to search for value in.
|
||||
* @param {Object} v Value to check for inside the array.
|
||||
* @return {Number/String} Index of item inside the array inside an object. Or -1 if it wasn't found.
|
||||
@@ -215,6 +285,7 @@ var tinymce = {
|
||||
/**
|
||||
* Extends an object with the specified other object(s).
|
||||
*
|
||||
* @method extend
|
||||
* @param {Object} o Object to extend with new items.
|
||||
* @param {Object} e..n Object(s) to extend the specified object with.
|
||||
* @return {Object} o New extended object, same reference as the input object.
|
||||
@@ -234,9 +305,12 @@ var tinymce = {
|
||||
return o;
|
||||
},
|
||||
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* Removes whitespace from the beginning and end of a string.
|
||||
*
|
||||
* @method trim
|
||||
* @param {String} s String to remove whitespace from.
|
||||
* @return {String} New string with removed whitespace.
|
||||
*/
|
||||
@@ -244,12 +318,11 @@ var tinymce = {
|
||||
return (s ? '' + s : '').replace(/^\s*|\s*$/g, '');
|
||||
},
|
||||
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* Creates a class, subclass or static singleton.
|
||||
* More details on this method can be found in the Wiki.
|
||||
*
|
||||
* @method create
|
||||
* @param {String} s Class name, inheritage and prefix.
|
||||
* @param {Object} o Collection of methods to add to the class.
|
||||
*/
|
||||
@@ -340,6 +413,7 @@ var tinymce = {
|
||||
/**
|
||||
* Executed the specified function for each item in a object tree.
|
||||
*
|
||||
* @method walk
|
||||
* @param {Object} o Object tree to walk though.
|
||||
* @param {function} f Function to call for each item.
|
||||
* @param {String} n Optional name of collection inside the objects to walk for example childNodes.
|
||||
@@ -364,6 +438,7 @@ var tinymce = {
|
||||
/**
|
||||
* Creates a namespace on a specific object.
|
||||
*
|
||||
* @method createNS
|
||||
* @param {String} n Namespace to create for example a.b.c.d.
|
||||
* @param {Object} o Optional object to add namespace to, defaults to window.
|
||||
* @return {Object} New namespace object the last item in path.
|
||||
@@ -389,6 +464,7 @@ var tinymce = {
|
||||
/**
|
||||
* Resolves a string and returns the object from a specific structure.
|
||||
*
|
||||
* @method resolve
|
||||
* @param {String} n Path to resolve for example a.b.c.d.
|
||||
* @param {Object} o Optional object to search though, defaults to window.
|
||||
* @return {Object} Last object in path or null if it couldn't be resolved.
|
||||
@@ -399,7 +475,7 @@ var tinymce = {
|
||||
o = o || window;
|
||||
|
||||
n = n.split('.');
|
||||
for (i=0, l = n.length; i<l; i++) {
|
||||
for (i = 0, l = n.length; i < l; i++) {
|
||||
o = o[n[i]];
|
||||
|
||||
if (!o)
|
||||
@@ -413,6 +489,7 @@ var tinymce = {
|
||||
* Adds an unload handler to the document. This handler will be executed when the document gets unloaded.
|
||||
* This method is useful for dealing with browser memory leaks where it might be vital to remove DOM references etc.
|
||||
*
|
||||
* @method addUnload
|
||||
* @param {function} f Function to execute before the document gets unloaded.
|
||||
* @param {Object} s Optional scope to execute the function in.
|
||||
* @return {function} Returns the specified unload handler function.
|
||||
@@ -443,7 +520,7 @@ var tinymce = {
|
||||
w.removeEventListener('unload', unload, false);
|
||||
|
||||
// Destroy references
|
||||
t.unloads = o = li = w = unload = null;
|
||||
t.unloads = o = li = w = unload = 0;
|
||||
|
||||
// Run garbarge collector on IE
|
||||
if (window.CollectGarbage)
|
||||
@@ -461,19 +538,22 @@ var tinymce = {
|
||||
d.detachEvent('onstop', stop);
|
||||
|
||||
// Call unload handler
|
||||
unload();
|
||||
if (unload)
|
||||
unload();
|
||||
|
||||
d = null;
|
||||
d = 0;
|
||||
};
|
||||
|
||||
// Fire unload when the currently loading page is stopped
|
||||
d.attachEvent('onstop', stop);
|
||||
if (d)
|
||||
d.attachEvent('onstop', stop);
|
||||
|
||||
// Remove onstop listener after a while to prevent the unload function
|
||||
// to execute if the user presses cancel in an onbeforeunload
|
||||
// confirm dialog and then presses the browser stop button
|
||||
window.setTimeout(function() {
|
||||
d.detachEvent('onstop', stop);
|
||||
if (d)
|
||||
d.detachEvent('onstop', stop);
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
@@ -496,6 +576,7 @@ var tinymce = {
|
||||
/**
|
||||
* Removes the specified function form the unload handler list.
|
||||
*
|
||||
* @method removeUnload
|
||||
* @param {function} f Function to remove from unload handler list.
|
||||
* @return {function} Removed function name or null if it wasn't found.
|
||||
*/
|
||||
@@ -516,6 +597,7 @@ var tinymce = {
|
||||
/**
|
||||
* Splits a string but removes the whitespace before and after each value.
|
||||
*
|
||||
* @method explode
|
||||
* @param {string} s String to split.
|
||||
* @param {string} d Delimiter to split by.
|
||||
*/
|
||||
|
||||
+13
-13
@@ -1,23 +1,26 @@
|
||||
/**
|
||||
* $Id: Button.js 793 2008-04-10 17:32:40Z spocke $
|
||||
* $Id: Button.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var DOM = tinymce.DOM;
|
||||
|
||||
/**#@+
|
||||
* @class This class is used to create a UI button. A button is basically a link
|
||||
/**
|
||||
* This class is used to create a UI button. A button is basically a link
|
||||
* that is styled to look like a button or icon.
|
||||
* @member tinymce.ui.Button
|
||||
* @base tinymce.ui.Control
|
||||
*
|
||||
* @class tinymce.ui.Button
|
||||
* @extends tinymce.ui.Control
|
||||
*/
|
||||
tinymce.create('tinymce.ui.Button:tinymce.ui.Control', {
|
||||
/**
|
||||
* Constructs a new button control instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method Button
|
||||
* @param {String} id Control id for the button.
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
*/
|
||||
@@ -26,14 +29,11 @@
|
||||
this.classPrefix = 'mceButton';
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Renders the button as a HTML string. This method is much faster than using the DOM and when
|
||||
* creating a whole toolbar with buttons it does make a lot of difference.
|
||||
*
|
||||
* @method renderHTML
|
||||
* @return {String} HTML for the button control element.
|
||||
*/
|
||||
renderHTML : function() {
|
||||
@@ -53,6 +53,8 @@
|
||||
/**
|
||||
* Post render handler. This function will be called after the UI has been
|
||||
* rendered so that events can be added.
|
||||
*
|
||||
* @method postRender
|
||||
*/
|
||||
postRender : function() {
|
||||
var t = this, s = t.settings;
|
||||
@@ -62,7 +64,5 @@
|
||||
return s.onclick.call(s.scope, e);
|
||||
});
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
+49
-16
@@ -1,23 +1,26 @@
|
||||
/**
|
||||
* $Id: ColorSplitButton.js 960 2008-11-12 18:30:32Z spocke $
|
||||
* $Id: ColorSplitButton.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each;
|
||||
|
||||
/**#@+
|
||||
* @class This class is used to create UI color split button. A color split button will present show a small color picker
|
||||
/**
|
||||
* This class is used to create UI color split button. A color split button will present show a small color picker
|
||||
* when you press the open menu.
|
||||
* @member tinymce.ui.ColorSplitButton
|
||||
* @base tinymce.ui.SplitButton
|
||||
*
|
||||
* @class tinymce.ui.ColorSplitButton
|
||||
* @extends tinymce.ui.SplitButton
|
||||
*/
|
||||
tinymce.create('tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton', {
|
||||
/**
|
||||
* Constructs a new color split button control instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method ColorSplitButton
|
||||
* @param {String} id Control id for the color split button.
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
*/
|
||||
@@ -26,25 +29,46 @@
|
||||
|
||||
t.parent(id, s);
|
||||
|
||||
/**
|
||||
* Settings object.
|
||||
*
|
||||
* @property settings
|
||||
* @type Object
|
||||
*/
|
||||
t.settings = s = tinymce.extend({
|
||||
colors : '000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF',
|
||||
grid_width : 8,
|
||||
default_color : '#888888'
|
||||
}, t.settings);
|
||||
|
||||
/**
|
||||
* Fires when the menu is shown.
|
||||
*
|
||||
* @event onShowMenu
|
||||
*/
|
||||
t.onShowMenu = new tinymce.util.Dispatcher(t);
|
||||
|
||||
/**
|
||||
* Fires when the menu is hidden.
|
||||
*
|
||||
* @event onHideMenu
|
||||
*/
|
||||
t.onHideMenu = new tinymce.util.Dispatcher(t);
|
||||
|
||||
/**
|
||||
* Current color value.
|
||||
*
|
||||
* @property value
|
||||
* @type String
|
||||
*/
|
||||
t.value = s.default_color;
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Shows the color menu. The color menu is a layer places under the button
|
||||
* and displays a table of colors for the user to pick from.
|
||||
*
|
||||
* @method showMenu
|
||||
*/
|
||||
showMenu : function() {
|
||||
var t = this, r, p, e, p2;
|
||||
@@ -72,6 +96,7 @@
|
||||
e = 0;
|
||||
|
||||
Event.add(DOM.doc, 'mousedown', t.hideMenu, t);
|
||||
t.onShowMenu.dispatch(t);
|
||||
|
||||
if (t._focused) {
|
||||
t._keyHandler = Event.add(t.id + '_menu', 'keydown', function(e) {
|
||||
@@ -82,8 +107,6 @@
|
||||
DOM.select('a', t.id + '_menu')[0].focus(); // Select first link
|
||||
}
|
||||
|
||||
t.onShowMenu.dispatch(t);
|
||||
|
||||
t.isMenuVisible = 1;
|
||||
},
|
||||
|
||||
@@ -91,6 +114,7 @@
|
||||
* Hides the color menu. The optional event parameter is used to check where the event occured so it
|
||||
* doesn't close them menu if it was a event inside the menu.
|
||||
*
|
||||
* @method hideMenu
|
||||
* @param {Event} e Optional event object.
|
||||
*/
|
||||
hideMenu : function(e) {
|
||||
@@ -100,7 +124,7 @@
|
||||
if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id + '_open';}))
|
||||
return;
|
||||
|
||||
if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceSplitButtonMenu');})) {
|
||||
if (!e || !DOM.getParent(e.target, '.mceSplitButtonMenu')) {
|
||||
DOM.removeClass(t.id, 'mceSplitButtonSelected');
|
||||
Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);
|
||||
Event.remove(t.id + '_menu', 'keydown', t._keyHandler);
|
||||
@@ -114,6 +138,8 @@
|
||||
|
||||
/**
|
||||
* Renders the menu to the DOM.
|
||||
*
|
||||
* @method renderMenu
|
||||
*/
|
||||
renderMenu : function() {
|
||||
var t = this, m, i = 0, s = t.settings, n, tb, tr, w;
|
||||
@@ -176,6 +202,7 @@
|
||||
/**
|
||||
* Sets the current color for the control and hides the menu if it should be visible.
|
||||
*
|
||||
* @method setColor
|
||||
* @param {String} c Color code value in hex for example: #FF00FF
|
||||
*/
|
||||
setColor : function(c) {
|
||||
@@ -188,6 +215,12 @@
|
||||
t.settings.onselect(c);
|
||||
},
|
||||
|
||||
/**
|
||||
* Post render event. This will be executed after the control has been rendered and can be used to
|
||||
* set states, add events to the control etc. It's recommended for subclasses of the control to call this method by using this.parent().
|
||||
*
|
||||
* @method postRender
|
||||
*/
|
||||
postRender : function() {
|
||||
var t = this, id = t.id;
|
||||
|
||||
@@ -199,6 +232,8 @@
|
||||
/**
|
||||
* Destroys the control. This means it will be removed from the DOM and any
|
||||
* events tied to it will also be removed.
|
||||
*
|
||||
* @method destroy
|
||||
*/
|
||||
destroy : function() {
|
||||
this.parent();
|
||||
@@ -207,7 +242,5 @@
|
||||
Event.clear(this.id + '_more');
|
||||
DOM.remove(this.id + '_menu');
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
+18
-11
@@ -1,36 +1,44 @@
|
||||
/**
|
||||
* $Id: Container.js 520 2008-01-07 16:30:32Z spocke $
|
||||
* $Id: Container.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* @class This class is the base class for all container controls like toolbars. This class should not
|
||||
/**
|
||||
* This class is the base class for all container controls like toolbars. This class should not
|
||||
* be instantiated directly other container controls should inherit from this one.
|
||||
* @member tinymce.ui.Container
|
||||
* @base tinymce.ui.Control
|
||||
*
|
||||
* @class tinymce.ui.Container
|
||||
* @extends tinymce.ui.Control
|
||||
*/
|
||||
tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {
|
||||
/**
|
||||
* Base contrustor a new container control instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method Container
|
||||
* @param {String} id Control id to use for the container.
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
*/
|
||||
Container : function(id, s) {
|
||||
this.parent(id, s);
|
||||
|
||||
/**
|
||||
* Array of controls added to the container.
|
||||
*
|
||||
* @property controls
|
||||
* @type Array
|
||||
*/
|
||||
this.controls = [];
|
||||
|
||||
this.lookup = {};
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds a control to the collection of controls for the container.
|
||||
*
|
||||
* @method add
|
||||
* @param {tinymce.ui.Control} c Control instance to add to the container.
|
||||
* @return {tinymce.ui.Control} Same control instance that got passed in.
|
||||
*/
|
||||
@@ -44,13 +52,12 @@ tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {
|
||||
/**
|
||||
* Returns a control by id from the containers collection.
|
||||
*
|
||||
* @method get
|
||||
* @param {String} n Id for the control to retrive.
|
||||
* @return {tinymce.ui.Control} Control instance by the specified name or undefined if it wasn't found.
|
||||
*/
|
||||
get : function(n) {
|
||||
return this.lookup[n];
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
|
||||
|
||||
+29
-18
@@ -1,23 +1,26 @@
|
||||
/**
|
||||
* $Id: Control.js 755 2008-03-29 19:14:42Z spocke $
|
||||
* $Id: Control.js 1190 2009-08-12 17:59:29Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
// Shorten class names
|
||||
var DOM = tinymce.DOM, is = tinymce.is;
|
||||
|
||||
/**#@+
|
||||
* @class This class is the base class for all controls like buttons, toolbars, containers. This class should not
|
||||
/**
|
||||
* This class is the base class for all controls like buttons, toolbars, containers. This class should not
|
||||
* be instantiated directly other controls should inherit from this one.
|
||||
* @member tinymce.ui.Control
|
||||
*
|
||||
* @class tinymce.ui.Control
|
||||
*/
|
||||
tinymce.create('tinymce.ui.Control', {
|
||||
/**
|
||||
* Constructs a new control instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method Control
|
||||
* @param {String} id Control id.
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
*/
|
||||
@@ -32,15 +35,12 @@
|
||||
this.active = 0;
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the disabled state for the control. This will add CSS classes to the
|
||||
* element that contains the control. So that it can be disabled visually.
|
||||
*
|
||||
* @param {bool} s Boolean state if the control should be disabled or not.
|
||||
* @method setDisabled
|
||||
* @param {Boolean} s Boolean state if the control should be disabled or not.
|
||||
*/
|
||||
setDisabled : function(s) {
|
||||
var e;
|
||||
@@ -67,7 +67,8 @@
|
||||
* Returns true/false if the control is disabled or not. This is a method since you can then
|
||||
* choose to check some class or some internal bool state in subclasses.
|
||||
*
|
||||
* @return {bool} true/false if the control is disabled or not.
|
||||
* @method isDisabled
|
||||
* @return {Boolean} true/false if the control is disabled or not.
|
||||
*/
|
||||
isDisabled : function() {
|
||||
return this.disabled;
|
||||
@@ -77,7 +78,8 @@
|
||||
* Sets the activated state for the control. This will add CSS classes to the
|
||||
* element that contains the control. So that it can be activated visually.
|
||||
*
|
||||
* @param {bool} s Boolean state if the control should be activated or not.
|
||||
* @method setActive
|
||||
* @param {Boolean} s Boolean state if the control should be activated or not.
|
||||
*/
|
||||
setActive : function(s) {
|
||||
if (s != this.active) {
|
||||
@@ -90,7 +92,8 @@
|
||||
* Returns true/false if the control is disabled or not. This is a method since you can then
|
||||
* choose to check some class or some internal bool state in subclasses.
|
||||
*
|
||||
* @return {bool} true/false if the control is disabled or not.
|
||||
* @method isActive
|
||||
* @return {Boolean} true/false if the control is disabled or not.
|
||||
*/
|
||||
isActive : function() {
|
||||
return this.active;
|
||||
@@ -99,8 +102,9 @@
|
||||
/**
|
||||
* Sets the specified class state for the control.
|
||||
*
|
||||
* @method setState
|
||||
* @param {String} c Class name to add/remove depending on state.
|
||||
* @param {bool} s True/false state if the class should be removed or added.
|
||||
* @param {Boolean} s True/false state if the class should be removed or added.
|
||||
*/
|
||||
setState : function(c, s) {
|
||||
var n = DOM.get(this.id);
|
||||
@@ -116,7 +120,8 @@
|
||||
/**
|
||||
* Returns true/false if the control has been rendered or not.
|
||||
*
|
||||
* @return {bool} State if the control has been rendered or not.
|
||||
* @method isRendered
|
||||
* @return {Boolean} State if the control has been rendered or not.
|
||||
*/
|
||||
isRendered : function() {
|
||||
return this.rendered;
|
||||
@@ -126,6 +131,7 @@
|
||||
* Renders the control as a HTML string. This method is much faster than using the DOM and when
|
||||
* creating a whole toolbar with buttons it does make a lot of difference.
|
||||
*
|
||||
* @method renderHTML
|
||||
* @return {String} HTML for the button control element.
|
||||
*/
|
||||
renderHTML : function() {
|
||||
@@ -134,6 +140,7 @@
|
||||
/**
|
||||
* Renders the control to the specified container element.
|
||||
*
|
||||
* @method renderTo
|
||||
* @param {Element} n HTML DOM element to add control to.
|
||||
*/
|
||||
renderTo : function(n) {
|
||||
@@ -143,6 +150,8 @@
|
||||
/**
|
||||
* Post render event. This will be executed after the control has been rendered and can be used to
|
||||
* set states, add events to the control etc. It's recommended for subclasses of the control to call this method by using this.parent().
|
||||
*
|
||||
* @method postRender
|
||||
*/
|
||||
postRender : function() {
|
||||
var t = this, b;
|
||||
@@ -164,6 +173,8 @@
|
||||
/**
|
||||
* Removes the control. This means it will be removed from the DOM and any
|
||||
* events tied to it will also be removed.
|
||||
*
|
||||
* @method remove
|
||||
*/
|
||||
remove : function() {
|
||||
DOM.remove(this.id);
|
||||
@@ -172,11 +183,11 @@
|
||||
|
||||
/**
|
||||
* Destroys the control will free any memory by removing event listeners etc.
|
||||
*
|
||||
* @method destroy
|
||||
*/
|
||||
destroy : function() {
|
||||
tinymce.dom.Event.clear(this.id);
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
+25
-16
@@ -1,23 +1,26 @@
|
||||
/**
|
||||
* $Id: DropMenu.js 939 2008-10-13 15:47:19Z spocke $
|
||||
* $Id: DropMenu.js 1190 2009-08-12 17:59:29Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event, Element = tinymce.dom.Element;
|
||||
|
||||
/**#@+
|
||||
* @class This class is used to create drop menus, a drop menu can be a
|
||||
/**
|
||||
* This class is used to create drop menus, a drop menu can be a
|
||||
* context menu, or a menu for a list box or a menu bar.
|
||||
* @member tinymce.ui.DropMenu
|
||||
* @base tinymce.ui.Menu
|
||||
*
|
||||
* @class tinymce.ui.DropMenu
|
||||
* @extends tinymce.ui.Menu
|
||||
*/
|
||||
tinymce.create('tinymce.ui.DropMenu:tinymce.ui.Menu', {
|
||||
/**
|
||||
* Constructs a new drop menu control instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method DropMenu
|
||||
* @param {String} id Button control id for the button.
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
*/
|
||||
@@ -38,13 +41,10 @@
|
||||
this.classPrefix = 'mceMenu';
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created a new sub menu for the drop menu control.
|
||||
*
|
||||
* @method createMenu
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
* @return {tinymce.ui.DropMenu} New drop menu instance.
|
||||
*/
|
||||
@@ -66,6 +66,8 @@
|
||||
|
||||
/**
|
||||
* Repaints the menu after new items have been added dynamically.
|
||||
*
|
||||
* @method update
|
||||
*/
|
||||
update : function() {
|
||||
var t = this, s = t.settings, tb = DOM.get('menu_' + t.id + '_tbl'), co = DOM.get('menu_' + t.id + '_co'), tw, th;
|
||||
@@ -92,6 +94,7 @@
|
||||
/**
|
||||
* Displays the menu at the specified cordinate.
|
||||
*
|
||||
* @method showMenu
|
||||
* @param {Number} x Horizontal position of the menu.
|
||||
* @param {Number} y Vertical position of the menu.
|
||||
* @param {Numner} px Optional parent X position used when menus are cascading.
|
||||
@@ -150,7 +153,7 @@
|
||||
|
||||
e = e.target;
|
||||
|
||||
if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, cp + 'ItemSub')) {
|
||||
if (e && (e = DOM.getParent(e, 'tr')) && !DOM.hasClass(e, cp + 'ItemSub')) {
|
||||
m = t.items[e.id];
|
||||
|
||||
if (m.isDisabled())
|
||||
@@ -177,7 +180,7 @@
|
||||
var m, r, mi;
|
||||
|
||||
e = e.target;
|
||||
if (e && (e = DOM.getParent(e, 'TR'))) {
|
||||
if (e && (e = DOM.getParent(e, 'tr'))) {
|
||||
m = t.items[e.id];
|
||||
|
||||
if (t.lastMenu)
|
||||
@@ -208,6 +211,8 @@
|
||||
|
||||
/**
|
||||
* Hides the displayed menu.
|
||||
*
|
||||
* @method hideMenu
|
||||
*/
|
||||
hideMenu : function(c) {
|
||||
var t = this, co = DOM.get('menu_' + t.id), e;
|
||||
@@ -236,6 +241,7 @@
|
||||
/**
|
||||
* Adds a new menu, menu item or sub classes of them to the drop menu.
|
||||
*
|
||||
* @method add
|
||||
* @param {tinymce.ui.Control} o Menu or menu item to add to the drop menu.
|
||||
* @return {tinymce.ui.Control} Same as the input control, the menu or menu item.
|
||||
*/
|
||||
@@ -253,7 +259,8 @@
|
||||
/**
|
||||
* Collapses the menu, this will hide the menu and all menu items.
|
||||
*
|
||||
* @param {bool} d Optional deep state. If this is set to true all children will be collapsed as well.
|
||||
* @method collapse
|
||||
* @param {Boolean} d Optional deep state. If this is set to true all children will be collapsed as well.
|
||||
*/
|
||||
collapse : function(d) {
|
||||
this.parent(d);
|
||||
@@ -263,6 +270,7 @@
|
||||
/**
|
||||
* Removes a specific sub menu or menu item from the drop menu.
|
||||
*
|
||||
* @method remove
|
||||
* @param {tinymce.ui.Control} o Menu item or menu to remove from drop menu.
|
||||
* @return {tinymce.ui.Control} Control instance or null if it wasn't found.
|
||||
*/
|
||||
@@ -275,6 +283,8 @@
|
||||
|
||||
/**
|
||||
* Destroys the menu. This will remove the menu from the DOM and any events added to it etc.
|
||||
*
|
||||
* @method destroy
|
||||
*/
|
||||
destroy : function() {
|
||||
var t = this, co = DOM.get('menu_' + t.id);
|
||||
@@ -291,6 +301,7 @@
|
||||
/**
|
||||
* Renders the specified menu node to the dom.
|
||||
*
|
||||
* @method renderNode
|
||||
* @return {Element} Container element for the drop menu.
|
||||
*/
|
||||
renderNode : function() {
|
||||
@@ -391,7 +402,5 @@
|
||||
|
||||
DOM.addClass(ro, 'mceLast');
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
+63
-16
@@ -1,23 +1,26 @@
|
||||
/**
|
||||
* $Id: ListBox.js 933 2008-09-27 08:41:46Z spocke $
|
||||
* $Id: ListBox.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;
|
||||
|
||||
/**#@+
|
||||
* @class This class is used to create list boxes/select list. This one will generate
|
||||
/**
|
||||
* This class is used to create list boxes/select list. This one will generate
|
||||
* a non native control. This one has the benefits of having visual items added.
|
||||
* @member tinymce.ui.ListBox
|
||||
* @base tinymce.ui.Control
|
||||
*
|
||||
* @class tinymce.ui.ListBox
|
||||
* @extends tinymce.ui.Control
|
||||
*/
|
||||
tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', {
|
||||
/**
|
||||
* Constructs a new listbox control instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method ListBox
|
||||
* @param {String} id Control id for the list box.
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
*/
|
||||
@@ -25,22 +28,51 @@
|
||||
var t = this;
|
||||
|
||||
t.parent(id, s);
|
||||
|
||||
/**
|
||||
* Array of ListBox items.
|
||||
*
|
||||
* @property items
|
||||
* @type Array
|
||||
*/
|
||||
t.items = [];
|
||||
|
||||
/**
|
||||
* Fires when the selection has been changed.
|
||||
*
|
||||
* @event onChange
|
||||
*/
|
||||
t.onChange = new Dispatcher(t);
|
||||
|
||||
/**
|
||||
* Fires after the element has been rendered to DOM.
|
||||
*
|
||||
* @event onPostRender
|
||||
*/
|
||||
t.onPostRender = new Dispatcher(t);
|
||||
|
||||
/**
|
||||
* Fires when a new item is added.
|
||||
*
|
||||
* @event onAdd
|
||||
*/
|
||||
t.onAdd = new Dispatcher(t);
|
||||
|
||||
/**
|
||||
* Fires when the menu gets rendered.
|
||||
*
|
||||
* @event onRenderMenu
|
||||
*/
|
||||
t.onRenderMenu = new tinymce.util.Dispatcher(this);
|
||||
|
||||
t.classPrefix = 'mceListBox';
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Selects a item/option by value. This will both add a visual selection to the
|
||||
* item and change the title of the control to the title of the option.
|
||||
*
|
||||
* @method select
|
||||
* @param {String/function} va Value to look for inside the list box or a function selector.
|
||||
*/
|
||||
select : function(va) {
|
||||
@@ -78,6 +110,7 @@
|
||||
* Selects a item/option by index. This will both add a visual selection to the
|
||||
* item and change the title of the control to the title of the option.
|
||||
*
|
||||
* @method selectByIndex
|
||||
* @param {String} idx Index to select, pass -1 to select menu/title of select box.
|
||||
*/
|
||||
selectByIndex : function(idx) {
|
||||
@@ -99,13 +132,13 @@
|
||||
}
|
||||
|
||||
e = 0;
|
||||
} else
|
||||
t.selectedValue = t.selectedIndex = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a option item to the list box.
|
||||
*
|
||||
* @method add
|
||||
* @param {String} n Title for the new option.
|
||||
* @param {String} v Value for the new option.
|
||||
* @param {Object} o Optional object with settings like for example class.
|
||||
@@ -126,6 +159,7 @@
|
||||
/**
|
||||
* Returns the number of items inside the list box.
|
||||
*
|
||||
* @method getLength
|
||||
* @param {Number} Number of items inside the list box.
|
||||
*/
|
||||
getLength : function() {
|
||||
@@ -136,6 +170,7 @@
|
||||
* Renders the list box as a HTML string. This method is much faster than using the DOM and when
|
||||
* creating a whole toolbar with buttons it does make a lot of difference.
|
||||
*
|
||||
* @method renderHTML
|
||||
* @return {String} HTML for the list box control element.
|
||||
*/
|
||||
renderHTML : function() {
|
||||
@@ -151,6 +186,8 @@
|
||||
|
||||
/**
|
||||
* Displays the drop menu with all items.
|
||||
*
|
||||
* @method showMenu
|
||||
*/
|
||||
showMenu : function() {
|
||||
var t = this, p1, p2, e = DOM.get(this.id), m;
|
||||
@@ -195,6 +232,8 @@
|
||||
|
||||
/**
|
||||
* Hides the drop menu.
|
||||
*
|
||||
* @method hideMenu
|
||||
*/
|
||||
hideMenu : function(e) {
|
||||
var t = this;
|
||||
@@ -203,7 +242,7 @@
|
||||
if (e && e.type == "mousedown" && (e.target.id == t.id + '_text' || e.target.id == t.id + '_open'))
|
||||
return;
|
||||
|
||||
if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {
|
||||
if (!e || !DOM.getParent(e.target, '.mceMenu')) {
|
||||
DOM.removeClass(t.id, t.classPrefix + 'Selected');
|
||||
Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);
|
||||
|
||||
@@ -214,6 +253,8 @@
|
||||
|
||||
/**
|
||||
* Renders the menu to the DOM.
|
||||
*
|
||||
* @method renderMenu
|
||||
*/
|
||||
renderMenu : function() {
|
||||
var t = this, m;
|
||||
@@ -253,6 +294,8 @@
|
||||
/**
|
||||
* Post render event. This will be executed after the control has been rendered and can be used to
|
||||
* set states, add events to the control etc. It's recommended for subclasses of the control to call this method by using this.parent().
|
||||
*
|
||||
* @method postRender
|
||||
*/
|
||||
postRender : function() {
|
||||
var t = this, cp = t.classPrefix;
|
||||
@@ -309,12 +352,16 @@
|
||||
t.onPostRender.dispatch(t, DOM.get(t.id));
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroys the ListBox i.e. clear memory and events.
|
||||
*
|
||||
* @method destroy
|
||||
*/
|
||||
destroy : function() {
|
||||
this.parent();
|
||||
|
||||
Event.clear(this.id + '_text');
|
||||
Event.clear(this.id + '_open');
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
+25
-17
@@ -1,23 +1,26 @@
|
||||
/**
|
||||
* $Id: Menu.js 766 2008-04-03 20:37:06Z spocke $
|
||||
* $Id: Menu.js 1190 2009-08-12 17:59:29Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;
|
||||
|
||||
/**#@+
|
||||
* @class This class is base class for all menu types like DropMenus etc. This class should not
|
||||
/**
|
||||
* This class is base class for all menu types like DropMenus etc. This class should not
|
||||
* be instantiated directly other menu controls should inherit from this one.
|
||||
* @member tinymce.ui.Menu
|
||||
* @base tinymce.ui.MenuItem
|
||||
*
|
||||
* @class tinymce.ui.Menu
|
||||
* @extends tinymce.ui.MenuItem
|
||||
*/
|
||||
tinymce.create('tinymce.ui.Menu:tinymce.ui.MenuItem', {
|
||||
/**
|
||||
* Constructs a new button control instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method Menu
|
||||
* @param {String} id Button control id for the button.
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
*/
|
||||
@@ -31,14 +34,11 @@
|
||||
t.onAddItem = new tinymce.util.Dispatcher(this);
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Expands the menu, this will show them menu and all menu items.
|
||||
*
|
||||
* @param {bool} d Optional deep state. If this is set to true all children will be expanded as well.
|
||||
* @method expand
|
||||
* @param {Boolean} d Optional deep state. If this is set to true all children will be expanded as well.
|
||||
*/
|
||||
expand : function(d) {
|
||||
var t = this;
|
||||
@@ -56,7 +56,8 @@
|
||||
/**
|
||||
* Collapses the menu, this will hide the menu and all menu items.
|
||||
*
|
||||
* @param {bool} d Optional deep state. If this is set to true all children will be collapsed as well.
|
||||
* @method collapse
|
||||
* @param {Boolean} d Optional deep state. If this is set to true all children will be collapsed as well.
|
||||
*/
|
||||
collapse : function(d) {
|
||||
var t = this;
|
||||
@@ -74,7 +75,8 @@
|
||||
/**
|
||||
* Returns true/false if the menu has been collapsed or not.
|
||||
*
|
||||
* @return {bool} True/false state if the menu has been collapsed or not.
|
||||
* @method isCollapsed
|
||||
* @return {Boolean} True/false state if the menu has been collapsed or not.
|
||||
*/
|
||||
isCollapsed : function() {
|
||||
return this.collapsed;
|
||||
@@ -83,6 +85,7 @@
|
||||
/**
|
||||
* Adds a new menu, menu item or sub classes of them to the drop menu.
|
||||
*
|
||||
* @method add
|
||||
* @param {tinymce.ui.Control} o Menu or menu item to add to the drop menu.
|
||||
* @return {tinymce.ui.Control} Same as the input control, the menu or menu item.
|
||||
*/
|
||||
@@ -98,6 +101,7 @@
|
||||
/**
|
||||
* Adds a menu separator between the menu items.
|
||||
*
|
||||
* @method addSeparator
|
||||
* @return {tinymce.ui.MenuItem} Menu item instance for the separator.
|
||||
*/
|
||||
addSeparator : function() {
|
||||
@@ -107,6 +111,7 @@
|
||||
/**
|
||||
* Adds a sub menu to the menu.
|
||||
*
|
||||
* @method addMenu
|
||||
* @param {Object} o Menu control or a object with settings to be created into an control.
|
||||
* @return {tinymce.ui.Menu} Menu control instance passed in or created.
|
||||
*/
|
||||
@@ -122,7 +127,8 @@
|
||||
/**
|
||||
* Returns true/false if the menu has sub menus or not.
|
||||
*
|
||||
* @return {bool} True/false state if the menu has sub menues or not.
|
||||
* @method hasMenus
|
||||
* @return {Boolean} True/false state if the menu has sub menues or not.
|
||||
*/
|
||||
hasMenus : function() {
|
||||
return this.menuCount !== 0;
|
||||
@@ -131,6 +137,7 @@
|
||||
/**
|
||||
* Removes a specific sub menu or menu item from the menu.
|
||||
*
|
||||
* @method remove
|
||||
* @param {tinymce.ui.Control} o Menu item or menu to remove from menu.
|
||||
* @return {tinymce.ui.Control} Control instance or null if it wasn't found.
|
||||
*/
|
||||
@@ -140,6 +147,8 @@
|
||||
|
||||
/**
|
||||
* Removes all menu items and sub menu items from the menu.
|
||||
*
|
||||
* @method removeAll
|
||||
*/
|
||||
removeAll : function() {
|
||||
var t = this;
|
||||
@@ -159,6 +168,7 @@
|
||||
/**
|
||||
* Created a new sub menu for the menu control.
|
||||
*
|
||||
* @method createMenu
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
* @return {tinymce.ui.Menu} New drop menu instance.
|
||||
*/
|
||||
@@ -169,7 +179,5 @@
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
+24
-13
@@ -5,34 +5,42 @@
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
|
||||
|
||||
/**#@+
|
||||
* @class This class is used to create a UI button. A button is basically a link
|
||||
/**
|
||||
* This class is used to create a UI button. A button is basically a link
|
||||
* that is styled to look like a button or icon.
|
||||
* @member tinymce.ui.Button
|
||||
* @base tinymce.ui.Control
|
||||
*
|
||||
* @class tinymce.ui.MenuButton
|
||||
* @extends tinymce.ui.Control
|
||||
*/
|
||||
tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button', {
|
||||
/**
|
||||
* Constructs a new split button control instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method MenuButton
|
||||
* @param {String} id Control id for the split button.
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
*/
|
||||
MenuButton : function(id, s) {
|
||||
this.parent(id, s);
|
||||
|
||||
/**
|
||||
* Fires when the menu is rendered.
|
||||
*
|
||||
* @event onRenderMenu
|
||||
*/
|
||||
this.onRenderMenu = new tinymce.util.Dispatcher(this);
|
||||
|
||||
s.menu_container = s.menu_container || DOM.doc.body;
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Shows the menu.
|
||||
*
|
||||
* @method showMenu
|
||||
*/
|
||||
showMenu : function() {
|
||||
var t = this, p1, p2, e = DOM.get(t.id), m;
|
||||
@@ -67,6 +75,8 @@
|
||||
|
||||
/**
|
||||
* Renders the menu to the DOM.
|
||||
*
|
||||
* @method renderMenu
|
||||
*/
|
||||
renderMenu : function() {
|
||||
var t = this, m;
|
||||
@@ -87,6 +97,7 @@
|
||||
* Hides the menu. The optional event parameter is used to check where the event occured so it
|
||||
* doesn't close them menu if it was a event inside the menu.
|
||||
*
|
||||
* @method hideMenu
|
||||
* @param {Event} e Optional event object.
|
||||
*/
|
||||
hideMenu : function(e) {
|
||||
@@ -96,7 +107,7 @@
|
||||
if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id || e.id === t.id + '_open';}))
|
||||
return;
|
||||
|
||||
if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {
|
||||
if (!e || !DOM.getParent(e.target, '.mceMenu')) {
|
||||
t.setState('Selected', 0);
|
||||
Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);
|
||||
if (t.menu)
|
||||
@@ -109,6 +120,8 @@
|
||||
/**
|
||||
* Post render handler. This function will be called after the UI has been
|
||||
* rendered so that events can be added.
|
||||
*
|
||||
* @method postRender
|
||||
*/
|
||||
postRender : function() {
|
||||
var t = this, s = t.settings;
|
||||
@@ -122,7 +135,5 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
+16
-15
@@ -1,23 +1,26 @@
|
||||
/**
|
||||
* $Id: MenuItem.js 520 2008-01-07 16:30:32Z spocke $
|
||||
* $Id: MenuItem.js 1190 2009-08-12 17:59:29Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;
|
||||
|
||||
/**#@+
|
||||
* @class This class is base class for all menu item types like DropMenus items etc. This class should not
|
||||
/**
|
||||
* This class is base class for all menu item types like DropMenus items etc. This class should not
|
||||
* be instantiated directly other menu items should inherit from this one.
|
||||
* @member tinymce.ui.MenuItem
|
||||
* @base tinymce.ui.Control
|
||||
*
|
||||
* @class tinymce.ui.MenuItem
|
||||
* @extends tinymce.ui.Control
|
||||
*/
|
||||
tinymce.create('tinymce.ui.MenuItem:tinymce.ui.Control', {
|
||||
/**
|
||||
* Constructs a new button control instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method MenuItem
|
||||
* @param {String} id Button control id for the button.
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
*/
|
||||
@@ -26,15 +29,12 @@
|
||||
this.classPrefix = 'mceMenuItem';
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the selected state for the control. This will add CSS classes to the
|
||||
* element that contains the control. So that it can be selected visually.
|
||||
*
|
||||
* @param {bool} s Boolean state if the control should be selected or not.
|
||||
* @method setSelected
|
||||
* @param {Boolean} s Boolean state if the control should be selected or not.
|
||||
*/
|
||||
setSelected : function(s) {
|
||||
this.setState('Selected', s);
|
||||
@@ -44,7 +44,8 @@
|
||||
/**
|
||||
* Returns true/false if the control is selected or not.
|
||||
*
|
||||
* @return {bool} true/false if the control is selected or not.
|
||||
* @method isSelected
|
||||
* @return {Boolean} true/false if the control is selected or not.
|
||||
*/
|
||||
isSelected : function() {
|
||||
return this.selected;
|
||||
@@ -53,6 +54,8 @@
|
||||
/**
|
||||
* Post render handler. This function will be called after the UI has been
|
||||
* rendered so that events can be added.
|
||||
*
|
||||
* @method postRender
|
||||
*/
|
||||
postRender : function() {
|
||||
var t = this;
|
||||
@@ -63,7 +66,5 @@
|
||||
if (is(t.selected))
|
||||
t.setSelected(t.selected);
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
+23
-16
@@ -1,23 +1,26 @@
|
||||
/**
|
||||
* $Id: NativeListBox.js 952 2008-11-03 17:56:04Z spocke $
|
||||
* $Id: NativeListBox.js 1190 2009-08-12 17:59:29Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;
|
||||
|
||||
/**#@+
|
||||
* @class This class is used to create list boxes/select list. This one will generate
|
||||
/**
|
||||
* This class is used to create list boxes/select list. This one will generate
|
||||
* a native control the way that the browser produces them by default.
|
||||
* @member tinymce.ui.NativeListBox
|
||||
* @base tinymce.ui.ListBox
|
||||
*
|
||||
* @class tinymce.ui.NativeListBox
|
||||
* @extends tinymce.ui.ListBox
|
||||
*/
|
||||
tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', {
|
||||
/**
|
||||
* Constructs a new button control instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method NativeListBox
|
||||
* @param {String} id Button control id for the button.
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
*/
|
||||
@@ -26,15 +29,12 @@
|
||||
this.classPrefix = 'mceNativeListBox';
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the disabled state for the control. This will add CSS classes to the
|
||||
* element that contains the control. So that it can be disabled visually.
|
||||
*
|
||||
* @param {bool} s Boolean state if the control should be disabled or not.
|
||||
* @method setDisabled
|
||||
* @param {Boolean} s Boolean state if the control should be disabled or not.
|
||||
*/
|
||||
setDisabled : function(s) {
|
||||
DOM.get(this.id).disabled = s;
|
||||
@@ -44,7 +44,8 @@
|
||||
* Returns true/false if the control is disabled or not. This is a method since you can then
|
||||
* choose to check some class or some internal bool state in subclasses.
|
||||
*
|
||||
* @return {bool} true/false if the control is disabled or not.
|
||||
* @method isDisabled
|
||||
* @return {Boolean} true/false if the control is disabled or not.
|
||||
*/
|
||||
isDisabled : function() {
|
||||
return DOM.get(this.id).disabled;
|
||||
@@ -54,7 +55,8 @@
|
||||
* Selects a item/option by value. This will both add a visual selection to the
|
||||
* item and change the title of the control to the title of the option.
|
||||
*
|
||||
* @param {String/function} va Value to look for inside the list box or a function selector.
|
||||
* @method select
|
||||
* @param {String/function} va Value to look for inside the list box or a function selector.
|
||||
*/
|
||||
select : function(va) {
|
||||
var t = this, fv, f;
|
||||
@@ -91,6 +93,7 @@
|
||||
* Selects a item/option by index. This will both add a visual selection to the
|
||||
* item and change the title of the control to the title of the option.
|
||||
*
|
||||
* @method selectByIndex
|
||||
* @param {String} idx Index to select, pass -1 to select menu/title of select box.
|
||||
*/
|
||||
selectByIndex : function(idx) {
|
||||
@@ -101,6 +104,7 @@
|
||||
/**
|
||||
* Adds a option item to the list box.
|
||||
*
|
||||
* @method add
|
||||
* @param {String} n Title for the new option.
|
||||
* @param {String} v Value for the new option.
|
||||
* @param {Object} o Optional object with settings like for example class.
|
||||
@@ -126,6 +130,8 @@
|
||||
|
||||
/**
|
||||
* Executes the specified callback function for the menu item. In this case when the user clicks the menu item.
|
||||
*
|
||||
* @method getLength
|
||||
*/
|
||||
getLength : function() {
|
||||
return DOM.get(this.id).options.length - 1;
|
||||
@@ -135,6 +141,7 @@
|
||||
* Renders the list box as a HTML string. This method is much faster than using the DOM and when
|
||||
* creating a whole toolbar with buttons it does make a lot of difference.
|
||||
*
|
||||
* @method renderHTML
|
||||
* @return {String} HTML for the list box control element.
|
||||
*/
|
||||
renderHTML : function() {
|
||||
@@ -154,6 +161,8 @@
|
||||
/**
|
||||
* Post render handler. This function will be called after the UI has been
|
||||
* rendered so that events can be added.
|
||||
*
|
||||
* @method postRender
|
||||
*/
|
||||
postRender : function() {
|
||||
var t = this, ch;
|
||||
@@ -192,7 +201,5 @@
|
||||
|
||||
t.onPostRender.dispatch(t, DOM.get(t.id));
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
+15
-11
@@ -1,34 +1,38 @@
|
||||
/**
|
||||
* $Id: Separator.js 756 2008-03-29 19:53:48Z spocke $
|
||||
* $Id: Separator.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* @class This class is used to create vertical separator between other controls.
|
||||
* @member tinymce.ui.Separator
|
||||
* @base tinymce.ui.Control
|
||||
/**
|
||||
* This class is used to create vertical separator between other controls.
|
||||
*
|
||||
* @class tinymce.ui.Separator
|
||||
* @extends tinymce.ui.Control
|
||||
*/
|
||||
tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
||||
/**
|
||||
* Separator constructor.
|
||||
*
|
||||
* @constructor
|
||||
* @method Separator
|
||||
* @param {String} id Control id to use for the Separator.
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
*/
|
||||
Separator : function(id, s) {
|
||||
this.parent(id, s);
|
||||
this.classPrefix = 'mceSeparator';
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Renders the separator as a HTML string. This method is much faster than using the DOM and when
|
||||
* creating a whole toolbar with buttons it does make a lot of difference.
|
||||
*
|
||||
* @method renderHTML
|
||||
* @return {String} HTML for the separator control element.
|
||||
*/
|
||||
renderHTML : function() {
|
||||
return tinymce.DOM.createHTML('span', {'class' : this.classPrefix});
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
|
||||
+13
-13
@@ -1,22 +1,25 @@
|
||||
/**
|
||||
* $Id: SplitButton.js 760 2008-04-01 14:13:07Z spocke $
|
||||
* $Id: SplitButton.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
(function(tinymce) {
|
||||
var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
|
||||
|
||||
/**#@+
|
||||
* @class This class is used to create a split button. A button with a menu attached to it.
|
||||
* @member tinymce.ui.SplitButton
|
||||
* @base tinymce.ui.Button
|
||||
/**
|
||||
* This class is used to create a split button. A button with a menu attached to it.
|
||||
*
|
||||
* @class tinymce.ui.SplitButton
|
||||
* @extends tinymce.ui.Button
|
||||
*/
|
||||
tinymce.create('tinymce.ui.SplitButton:tinymce.ui.MenuButton', {
|
||||
/**
|
||||
* Constructs a new split button control instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method SplitButton
|
||||
* @param {String} id Control id for the split button.
|
||||
* @param {Object} s Optional name/value settings object.
|
||||
*/
|
||||
@@ -25,14 +28,11 @@
|
||||
this.classPrefix = 'mceSplitButton';
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Renders the split button as a HTML string. This method is much faster than using the DOM and when
|
||||
* creating a whole toolbar with buttons it does make a lot of difference.
|
||||
*
|
||||
* @method renderHTML
|
||||
* @return {String} HTML for the split button control element.
|
||||
*/
|
||||
renderHTML : function() {
|
||||
@@ -58,6 +58,8 @@
|
||||
/**
|
||||
* Post render handler. This function will be called after the UI has been
|
||||
* rendered so that events can be added.
|
||||
*
|
||||
* @method postRender
|
||||
*/
|
||||
postRender : function() {
|
||||
var t = this, s = t.settings;
|
||||
@@ -93,7 +95,5 @@
|
||||
Event.clear(this.id + '_action');
|
||||
Event.clear(this.id + '_open');
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
})(tinymce);
|
||||
|
||||
+7
-11
@@ -1,24 +1,22 @@
|
||||
/**
|
||||
* $Id: Toolbar.js 706 2008-03-11 20:38:31Z spocke $
|
||||
* $Id: Toolbar.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* @class This class is used to create toolbars a toolbar is a container for other controls like buttons etc.
|
||||
* @member tinymce.ui.Toolbar
|
||||
* @base tinymce.ui.Container
|
||||
/**
|
||||
* This class is used to create toolbars a toolbar is a container for other controls like buttons etc.
|
||||
*
|
||||
* @class tinymce.ui.Toolbar
|
||||
* @extends tinymce.ui.Container
|
||||
*/
|
||||
tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Renders the toolbar as a HTML string. This method is much faster than using the DOM and when
|
||||
* creating a whole toolbar with buttons it does make a lot of difference.
|
||||
*
|
||||
* @method renderHTML
|
||||
* @return {String} HTML for the toolbar control.
|
||||
*/
|
||||
renderHTML : function() {
|
||||
@@ -81,6 +79,4 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
||||
|
||||
return dom.createHTML('table', {id : t.id, 'class' : 'mceToolbar' + (s['class'] ? ' ' + s['class'] : ''), cellpadding : '0', cellspacing : '0', align : t.settings.align || ''}, '<tbody><tr>' + h + '</tr></tbody>');
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
|
||||
+12
-12
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: Cookie.js 520 2008-01-07 16:30:32Z spocke $
|
||||
* $Id: Cookie.js 1183 2009-08-10 15:37:31Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
@@ -8,19 +8,17 @@
|
||||
(function() {
|
||||
var each = tinymce.each;
|
||||
|
||||
/**#@+
|
||||
* @class This class contains simple cookie manangement functions.
|
||||
* @member tinymce.util.Cookie
|
||||
/**
|
||||
* This class contains simple cookie manangement functions.
|
||||
*
|
||||
* @class tinymce.util.Cookie
|
||||
* @static
|
||||
*/
|
||||
tinymce.create('static tinymce.util.Cookie', {
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parses the specified query string into an name/value object.
|
||||
*
|
||||
* @method getHash
|
||||
* @param {String} n String to parse into a n Hashtable object.
|
||||
* @return {Object} Name/Value object with items parsed from querystring.
|
||||
*/
|
||||
@@ -41,9 +39,10 @@
|
||||
/**
|
||||
* Sets a hashtable name/value object to a cookie.
|
||||
*
|
||||
* @method setHash
|
||||
* @param {String} n Name of the cookie.
|
||||
* @param {Object} v Hashtable object to set as cookie.
|
||||
* @param {Date} d Optional date object for the expiration of the cookie.
|
||||
* @param {Date} e Optional date object for the expiration of the cookie.
|
||||
* @param {String} p Optional path to restrict the cookie to.
|
||||
* @param {String} d Optional domain to restrict the cookie to.
|
||||
* @param {String} s Is the cookie secure or not.
|
||||
@@ -61,6 +60,7 @@
|
||||
/**
|
||||
* Gets the raw data of a cookie by name.
|
||||
*
|
||||
* @method get
|
||||
* @param {String} n Name of cookie to retrive.
|
||||
* @return {String} Cookie data string.
|
||||
*/
|
||||
@@ -92,9 +92,10 @@
|
||||
/**
|
||||
* Sets a raw cookie string.
|
||||
*
|
||||
* @method set
|
||||
* @param {String} n Name of the cookie.
|
||||
* @param {String} v Raw cookie data.
|
||||
* @param {Date} d Optional date object for the expiration of the cookie.
|
||||
* @param {Date} e Optional date object for the expiration of the cookie.
|
||||
* @param {String} p Optional path to restrict the cookie to.
|
||||
* @param {String} d Optional domain to restrict the cookie to.
|
||||
* @param {String} s Is the cookie secure or not.
|
||||
@@ -110,6 +111,7 @@
|
||||
/**
|
||||
* Removes/deletes a cookie by name.
|
||||
*
|
||||
* @method remove
|
||||
* @param {String} n Cookie name to remove/delete.
|
||||
* @param {Strong} p Optional path to remove the cookie from.
|
||||
*/
|
||||
@@ -120,7 +122,5 @@
|
||||
|
||||
this.set(n, '', d, p, d);
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
|
||||
+10
-8
@@ -1,14 +1,15 @@
|
||||
/**
|
||||
* $Id: Dispatcher.js 743 2008-03-23 17:47:33Z spocke $
|
||||
* $Id: Dispatcher.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* @class This class is used to dispatch event to observers/listeners.
|
||||
/**
|
||||
* This class is used to dispatch event to observers/listeners.
|
||||
* All internal events inside TinyMCE uses this class.
|
||||
* @member tinymce.util.Dispatcher
|
||||
*
|
||||
* @class tinymce.util.Dispatcher
|
||||
*/
|
||||
tinymce.create('tinymce.util.Dispatcher', {
|
||||
scope : null,
|
||||
@@ -18,6 +19,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
||||
* Constructs a new event dispatcher object.
|
||||
*
|
||||
* @constructor
|
||||
* @method Dispatcher
|
||||
* @param {Object} s Optional default execution scope for all observer functions.
|
||||
*/
|
||||
Dispatcher : function(s) {
|
||||
@@ -25,13 +27,10 @@ tinymce.create('tinymce.util.Dispatcher', {
|
||||
this.listeners = [];
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add an observer function to be executed when a dispatch call is done.
|
||||
*
|
||||
* @method add
|
||||
* @param {function} cb Callback function to execute when a dispatch event occurs.
|
||||
* @param {Object} s Optional execution scope, defaults to the one specified in the class constructor.
|
||||
* @return {function} Returns the same function as the one passed on.
|
||||
@@ -45,6 +44,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
||||
/**
|
||||
* Add an observer function to be executed to the top of the list of observers.
|
||||
*
|
||||
* @method addToTop
|
||||
* @param {function} cb Callback function to execute when a dispatch event occurs.
|
||||
* @param {Object} s Optional execution scope, defaults to the one specified in the class constructor.
|
||||
* @return {function} Returns the same function as the one passed on.
|
||||
@@ -58,6 +58,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
||||
/**
|
||||
* Removes an observer function.
|
||||
*
|
||||
* @method remove
|
||||
* @param {function} cb Observer function to remove.
|
||||
* @return {function} The same function that got passed in or null if it wasn't found.
|
||||
*/
|
||||
@@ -78,6 +79,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
||||
/**
|
||||
* Dispatches an event to all observers/listeners.
|
||||
*
|
||||
* @method dispatch
|
||||
* @param {Object} .. Any number of arguments to dispatch.
|
||||
* @return {Object} Last observer functions return value.
|
||||
*/
|
||||
|
||||
+8
-9
@@ -1,23 +1,21 @@
|
||||
/**
|
||||
* $Id: JSON.js 920 2008-09-09 14:05:33Z spocke $
|
||||
* $Id: JSON.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* @class JSON parser and serializer class.
|
||||
* @member tinymce.util.JSON
|
||||
/**
|
||||
* JSON parser and serializer class.
|
||||
*
|
||||
* @class tinymce.util.JSON
|
||||
* @static
|
||||
*/
|
||||
tinymce.create('static tinymce.util.JSON', {
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Serializes the specified object as a JSON string.
|
||||
*
|
||||
* @method serialize
|
||||
* @param {Object} o Object to serialize as a JSON string.
|
||||
* @return {string} JSON string serialized from input.
|
||||
*/
|
||||
@@ -45,7 +43,7 @@ tinymce.create('static tinymce.util.JSON', {
|
||||
}
|
||||
|
||||
if (t == 'object') {
|
||||
if (o instanceof Array) {
|
||||
if (o.hasOwnProperty && o instanceof Array) {
|
||||
for (i=0, v = '['; i<o.length; i++)
|
||||
v += (i > 0 ? ',' : '') + s(o[i]);
|
||||
|
||||
@@ -66,6 +64,7 @@ tinymce.create('static tinymce.util.JSON', {
|
||||
/**
|
||||
* Unserializes/parses the specified JSON string into a object.
|
||||
*
|
||||
* @method parse
|
||||
* @param {string} s JSON String to parse into a JavaScript object.
|
||||
* @return {Object} Object from input JSON string or undefined if it failed.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* $Id: JSON.js 920 2008-09-09 14:05:33Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
tinymce.create('static tinymce.util.JSONP', {
|
||||
callbacks : {},
|
||||
count : 0,
|
||||
|
||||
send : function(o) {
|
||||
var t = this, dom = tinymce.DOM, count = o.count !== undefined ? o.count : t.count, id = 'tinymce_jsonp_' + count;
|
||||
|
||||
t.callbacks[count] = function(json) {
|
||||
dom.remove(id);
|
||||
delete t.callbacks[count];
|
||||
|
||||
o.callback(json);
|
||||
};
|
||||
|
||||
dom.add(dom.doc.body, 'script', {id : id , src : o.url, type : 'text/javascript'});
|
||||
t.count++;
|
||||
}
|
||||
});
|
||||
+9
-10
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: JSONRequest.js 578 2008-01-31 11:05:10Z spocke $
|
||||
* $Id: JSONRequest.js 1176 2009-08-04 09:42:14Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
|
||||
@@ -8,15 +8,17 @@
|
||||
(function() {
|
||||
var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR;
|
||||
|
||||
/**#@+
|
||||
* @class This class enables you to use JSON-RPC to call backend methods.
|
||||
* @member tinymce.util.JSONRequest
|
||||
/**
|
||||
* This class enables you to use JSON-RPC to call backend methods.
|
||||
*
|
||||
* @class tinymce.util.JSONRequest
|
||||
*/
|
||||
tinymce.create('tinymce.util.JSONRequest', {
|
||||
/**
|
||||
* Constructs a new JSONRequest instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method JSONRequest
|
||||
* @param {Object} s Optional settings object.
|
||||
*/
|
||||
JSONRequest : function(s) {
|
||||
@@ -25,13 +27,10 @@
|
||||
this.count = 0;
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sends a JSON-RPC call. Consult the Wiki API documentation for more details on what you can pass to this function.
|
||||
*
|
||||
* @method send
|
||||
* @param {Object} o Call object where there are three field id, method and params this object should also contain callbacks etc.
|
||||
*/
|
||||
send : function(o) {
|
||||
@@ -75,13 +74,13 @@
|
||||
* Simple helper function to send a JSON-RPC request without the need to initialize an object.
|
||||
* Consult the Wiki API documentation for more details on what you can pass to this function.
|
||||
*
|
||||
* @method sendRPC
|
||||
* @static
|
||||
* @param {Object} o Call object where there are three field id, method and params this object should also contain callbacks etc.
|
||||
*/
|
||||
sendRPC : function(o) {
|
||||
return new tinymce.util.JSONRequest().send(o);
|
||||
}
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
}());
|
||||
+34
-19
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: URI.js 928 2008-09-14 15:14:22Z spocke $
|
||||
* $Id: URI.js 1211 2009-08-20 14:09:00Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
@@ -8,26 +8,30 @@
|
||||
(function() {
|
||||
var each = tinymce.each;
|
||||
|
||||
/**#@+
|
||||
* @class This class handles parsing, modification and serialization of URI/URL strings.
|
||||
* @member tinymce.util.URI
|
||||
/**
|
||||
* This class handles parsing, modification and serialization of URI/URL strings.
|
||||
* @class tinymce.util.URI
|
||||
*/
|
||||
tinymce.create('tinymce.util.URI', {
|
||||
/**
|
||||
* Constucts a new URI instance.
|
||||
*
|
||||
* @constructor
|
||||
* @method URI
|
||||
* @param {String} u URI string to parse.
|
||||
* @param {Object} s Optional settings object.
|
||||
*/
|
||||
URI : function(u, s) {
|
||||
var t = this, o, a, b;
|
||||
|
||||
// Trim whitespace
|
||||
u = tinymce.trim(u);
|
||||
|
||||
// Default settings
|
||||
s = t.settings = s || {};
|
||||
|
||||
// Strange app protocol or local anchor
|
||||
if (/^(mailto|news|javascript|about):/i.test(u) || /^\s*#/.test(u)) {
|
||||
if (/^(mailto|tel|news|javascript|about|data):/i.test(u) || /^\s*#/.test(u)) {
|
||||
t.source = u;
|
||||
return;
|
||||
}
|
||||
@@ -36,8 +40,8 @@
|
||||
if (u.indexOf('/') === 0 && u.indexOf('//') !== 0)
|
||||
u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u;
|
||||
|
||||
// Relative path
|
||||
if (u.indexOf(':/') === -1 && u.indexOf('//') !== 0)
|
||||
// Relative path http:// or protocol relative //path
|
||||
if (!/^\w*:?\/\//.test(u))
|
||||
u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u);
|
||||
|
||||
// Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)
|
||||
@@ -72,13 +76,10 @@
|
||||
//t.path = t.path || '/';
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the internal path part of the URI.
|
||||
*
|
||||
* @method setPath
|
||||
* @param {string} p Path string to set.
|
||||
*/
|
||||
setPath : function(p) {
|
||||
@@ -99,6 +100,7 @@
|
||||
/**
|
||||
* Converts the specified URI into a relative URI based on the current URI instance location.
|
||||
*
|
||||
* @method toRelative
|
||||
* @param {String} u URI to convert into a relative path/URI.
|
||||
* @return {String} Relative URI from the point specified in the current URI instance.
|
||||
*/
|
||||
@@ -130,19 +132,21 @@
|
||||
/**
|
||||
* Converts the specified URI into a absolute URI based on the current URI instance location.
|
||||
*
|
||||
* @method toAbsolute
|
||||
* @param {String} u URI to convert into a relative path/URI.
|
||||
* @param {bool} nh No host and protocol prefix.
|
||||
* @param {Boolean} nh No host and protocol prefix.
|
||||
* @return {String} Absolute URI from the point specified in the current URI instance.
|
||||
*/
|
||||
toAbsolute : function(u, nh) {
|
||||
var u = new tinymce.util.URI(u, {base_uri : this});
|
||||
|
||||
return u.getURI(this.host == u.host ? nh : 0);
|
||||
return u.getURI(this.host == u.host && this.protocol == u.protocol ? nh : 0);
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts a absolute path into a relative path.
|
||||
*
|
||||
* @method toRelPath
|
||||
* @param {String} base Base point to convert the path from.
|
||||
* @param {String} path Absolute path to convert into a relative path.
|
||||
*/
|
||||
@@ -191,13 +195,15 @@
|
||||
/**
|
||||
* Converts a relative path into a absolute path.
|
||||
*
|
||||
* @method toAbsPath
|
||||
* @param {String} base Base point to convert the path from.
|
||||
* @param {String} path Relative path to convert into an absolute path.
|
||||
*/
|
||||
toAbsPath : function(base, path) {
|
||||
var i, nb = 0, o = [];
|
||||
var i, nb = 0, o = [], tr, outPath;
|
||||
|
||||
// Split paths
|
||||
tr = /\/$/.test(path) ? '/' : '';
|
||||
base = base.split('/');
|
||||
path = path.split('/');
|
||||
|
||||
@@ -234,15 +240,26 @@
|
||||
|
||||
// If /a/b/c or /
|
||||
if (i <= 0)
|
||||
return '/' + o.reverse().join('/');
|
||||
outPath = o.reverse().join('/');
|
||||
else
|
||||
outPath = base.slice(0, i).join('/') + '/' + o.reverse().join('/');
|
||||
|
||||
return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/');
|
||||
// Add front / if it's needed
|
||||
if (outPath.indexOf('/') !== 0)
|
||||
outPath = '/' + outPath;
|
||||
|
||||
// Add traling / if it's needed
|
||||
if (tr && outPath.lastIndexOf('/') !== outPath.length - 1)
|
||||
outPath += tr;
|
||||
|
||||
return outPath;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the full URI of the internal structure.
|
||||
*
|
||||
* @param {bool} nh Optional no host and protocol part. Defaults to false.
|
||||
* @method getURI
|
||||
* @param {Boolean} nh Optional no host and protocol part. Defaults to false.
|
||||
*/
|
||||
getURI : function(nh) {
|
||||
var s, t = this;
|
||||
@@ -279,7 +296,5 @@
|
||||
|
||||
return t.source;
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -1,424 +0,0 @@
|
||||
/**
|
||||
* $Id: UnitTester.js 394 2007-11-15 18:05:17Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
// Shorten names
|
||||
var each = tinymce.each, DOM = tinymce.DOM;
|
||||
|
||||
/**#@+
|
||||
* @class This class is a simple Unit testing class. Provides simple methods for
|
||||
* test case and asserts execution.
|
||||
* XML Parser class. This class is only available for the dev version of TinyMCE.
|
||||
* @member tinymce.util.UnitTester
|
||||
*/
|
||||
tinymce.create('tinymce.util.UnitTester', {
|
||||
/**
|
||||
* Constructs a new UnitTester instance.
|
||||
*
|
||||
* @constructor
|
||||
* @param {String} id Element ID to log execution events to.
|
||||
* @param {Object} s Optional settings object.
|
||||
*/
|
||||
UnitTester : function(id, s) {
|
||||
this.id = id;
|
||||
this.cases = {};
|
||||
this.settings = tinymce.extend({
|
||||
debug : false,
|
||||
log_skipped : false
|
||||
}, s);
|
||||
},
|
||||
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fakes a mouse event.
|
||||
*
|
||||
* @param {Element/String} e DOM element object or element id to send fake event to.
|
||||
* @param {String} na Event name to fake like "click".
|
||||
* @param {Object} o Optional object with data to send with the event like cordinates.
|
||||
*/
|
||||
fakeMouseEvent : function(e, na, o) {
|
||||
var ev;
|
||||
|
||||
o = tinymce.extend({
|
||||
screenX : 0,
|
||||
screenY : 0,
|
||||
clientX : 0,
|
||||
clientY : 0
|
||||
}, o);
|
||||
|
||||
e = DOM.get(e);
|
||||
|
||||
if (e.fireEvent) {
|
||||
ev = document.createEventObject();
|
||||
tinymce.extend(ev, o);
|
||||
e.fireEvent('on' + na, ev);
|
||||
return;
|
||||
}
|
||||
|
||||
ev = document.createEvent('MouseEvents');
|
||||
|
||||
if (ev.initMouseEvent)
|
||||
ev.initMouseEvent(na, true, true, window, 1, o.screenX, o.screenY, o.clientX, o.clientY, false, false, true, false, 0, null);
|
||||
|
||||
e.dispatchEvent(ev);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fakes a key event.
|
||||
*
|
||||
* @param {Element/String} e DOM element object or element id to send fake event to.
|
||||
* @param {String} na Event name to fake like "keydown".
|
||||
* @param {Object} o Optional object with data to send with the event like keyCode and charCode.
|
||||
*/
|
||||
fakeKeyEvent : function(e, na, o) {
|
||||
var ev;
|
||||
|
||||
o = tinymce.extend({
|
||||
keyCode : 13,
|
||||
charCode : 0
|
||||
}, o);
|
||||
|
||||
e = DOM.get(e);
|
||||
|
||||
if (e.fireEvent) {
|
||||
ev = document.createEventObject();
|
||||
tinymce.extend(ev, o);
|
||||
e.fireEvent('on' + na, ev);
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.createEvent) {
|
||||
try {
|
||||
// Fails in Safari
|
||||
ev = document.createEvent('KeyEvents');
|
||||
ev.initKeyEvent(na, true, true, window, false, false, false, false, o.keyCode, o.charCode);
|
||||
} catch (ex) {
|
||||
ev = document.createEvent('Events');
|
||||
ev.initEvent(na, true, true);
|
||||
|
||||
ev.keyCode = o.keyCode;
|
||||
ev.charCode = o.charCode;
|
||||
}
|
||||
} else {
|
||||
ev = document.createEvent('UIEvents');
|
||||
|
||||
if (ev.initUIEvent)
|
||||
ev.initUIEvent(na, true, true, window, 1);
|
||||
|
||||
ev.keyCode = o.keyCode;
|
||||
ev.charCode = o.charCode;
|
||||
}
|
||||
|
||||
e.dispatchEvent(ev);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a test with units.
|
||||
*
|
||||
* @param {String} n Name of test.
|
||||
* @param {Object} t Name/Value collection with functions to be executed.
|
||||
*/
|
||||
add : function(n, t) {
|
||||
this.cases[n] = t;
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets the UnitTester and removes any contents from the log.
|
||||
*/
|
||||
reset : function() {
|
||||
DOM.get(this.id).innerHTML = '';
|
||||
},
|
||||
|
||||
/**
|
||||
* TODO: FIX ME!
|
||||
*/
|
||||
runAsync : function(n, te) {
|
||||
var t = this, c, st;
|
||||
|
||||
if (!t.started) {
|
||||
st = t.stats = {
|
||||
tests : 0,
|
||||
asserts : 0,
|
||||
failed_tests : 0,
|
||||
failed_asserts : 0,
|
||||
skipped_asserts : 0,
|
||||
exceptions : 0,
|
||||
total : 0
|
||||
};
|
||||
|
||||
t.started = 1;
|
||||
|
||||
each(t.cases, function(c) {
|
||||
each(c, function(x, k) {
|
||||
if (k == 'setup' || k == 'teardown')
|
||||
return;
|
||||
|
||||
if (te && k != te)
|
||||
return;
|
||||
|
||||
st.total++;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
c = t.cases[n];
|
||||
|
||||
if (c.setup)
|
||||
c.setup.call(t);
|
||||
|
||||
each(c, function(v, k) {
|
||||
if (k == 'setup' || k == 'teardown')
|
||||
return;
|
||||
|
||||
if (te && k != te)
|
||||
return;
|
||||
|
||||
st.tests++;
|
||||
t.failedTest = 0;
|
||||
t.assertCount = 0;
|
||||
|
||||
t.log('Running test: ' + n + '.' + k + ' (' + st.tests + '/' + st.total + ')');
|
||||
|
||||
if (!t.settings.debug) {
|
||||
try {
|
||||
v.call(t);
|
||||
} catch (ex) {
|
||||
t.logFailure('Exception occured:', ex);
|
||||
st.exceptions++;
|
||||
t.failedTest = 1;
|
||||
}
|
||||
} else
|
||||
v.call(t);
|
||||
|
||||
if (t.failedTest)
|
||||
st.failed_tests++;
|
||||
});
|
||||
|
||||
if (c.teardown)
|
||||
c.teardown.call(t);
|
||||
|
||||
if (st.tests >= st.total) {
|
||||
if (st.failed_tests > 0) {
|
||||
t.logFailure(t.format('Runned %d of %d tests, %d failed.', st.tests, st.tests, st.failed_tests));
|
||||
t.logFailure(t.format('Runned %d of %d asserts, %d failed.', st.asserts, st.asserts, st.failed_asserts));
|
||||
|
||||
if (st.skipped_asserts > 0)
|
||||
t.logFailure(t.format('Due to browser bugs %d asserts where skipped.', st.skipped_asserts));
|
||||
} else {
|
||||
t.logSuccess(t.format('Runned %d of %d tests, %d failed.', st.tests, st.tests, st.failed_tests));
|
||||
t.logSuccess(t.format('Runned %d of %d asserts, %d failed.', st.asserts, st.asserts, st.failed_asserts));
|
||||
|
||||
if (st.skipped_asserts > 0)
|
||||
t.logSuccess(t.format('Due to browser bugs %d asserts where skipped.', st.skipped_asserts));
|
||||
}
|
||||
|
||||
t.started = 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Runs the test(s). Default is execution of all added tests and units.
|
||||
*
|
||||
* @param {String} Optional test name to execute.
|
||||
* @param {String} Optional unit to execute inside the test.
|
||||
*/
|
||||
run : function(n, te) {
|
||||
var t = this, st, o;
|
||||
|
||||
st = t.stats = {
|
||||
tests : 0,
|
||||
asserts : 0,
|
||||
failed_tests : 0,
|
||||
failed_asserts : 0,
|
||||
skipped_asserts : 0,
|
||||
exceptions : 0
|
||||
};
|
||||
|
||||
if (n) {
|
||||
o = {};
|
||||
o[n] = this.cases[n];
|
||||
} else
|
||||
o = this.cases;
|
||||
|
||||
each(o, function(c, n) {
|
||||
var tc = 0;
|
||||
|
||||
if (c.setup)
|
||||
c.setup.call(t);
|
||||
|
||||
each(c, function(v, k) {
|
||||
if (k == 'setup' || k == 'teardown')
|
||||
return;
|
||||
|
||||
if (te && k != te)
|
||||
return;
|
||||
|
||||
st.tests++;
|
||||
t.failedTest = 0;
|
||||
t.assertCount = 0;
|
||||
|
||||
t.log('Running test: ' + n + ', ' + k);
|
||||
|
||||
if (!t.settings.debug) {
|
||||
try {
|
||||
v.call(t);
|
||||
} catch (ex) {
|
||||
t.logFailure('Exception occured:', ex);
|
||||
st.exceptions++;
|
||||
t.failedTest = 1;
|
||||
}
|
||||
} else
|
||||
v.call(t);
|
||||
|
||||
if (t.failedTest)
|
||||
st.failed_tests++;
|
||||
});
|
||||
|
||||
if (c.teardown)
|
||||
c.teardown.call(t);
|
||||
});
|
||||
|
||||
if (st.failed_tests > 0) {
|
||||
t.logFailure(t.format('Runned %d of %d tests, %d failed.', st.tests, st.tests, st.failed_tests));
|
||||
t.logFailure(t.format('Runned %d of %d asserts, %d failed.', st.asserts, st.asserts, st.failed_asserts));
|
||||
|
||||
if (st.skipped_asserts > 0)
|
||||
t.logFailure(t.format('Due to browser bugs %d asserts where skipped.', st.skipped_asserts));
|
||||
} else {
|
||||
t.logSuccess(t.format('Runned %d of %d tests, %d failed.', st.tests, st.tests, st.failed_tests));
|
||||
t.logSuccess(t.format('Runned %d of %d asserts, %d failed.', st.asserts, st.asserts, st.failed_asserts));
|
||||
|
||||
if (st.skipped_asserts > 0)
|
||||
t.logSuccess(t.format('Due to browser bugs %d asserts where skipped.', st.skipped_asserts));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* String format function.
|
||||
*
|
||||
* @param {String} s String with %d %s things that gets replaced.
|
||||
* @param {Object} .. Optional arguments to be placed in string.
|
||||
* @return {String} Formatted string.
|
||||
*/
|
||||
format : function(s) {
|
||||
var i = 1, a = arguments;
|
||||
|
||||
return s.replace(/%([ds])/g, function(m, t) {
|
||||
return '' + a[i++];
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the specified input param is true.
|
||||
*
|
||||
* @param {bool} e Object/item to check if true.
|
||||
* @param {String} m Optional message to output.
|
||||
* @param {bool} sk Skip error output if this is true.
|
||||
*/
|
||||
is : function(e, m, sk) {
|
||||
this.stats.asserts++;
|
||||
|
||||
if (!e)
|
||||
this.fail(this.format(m || '[%d] Assert failed, value not true: %s', this.assertCount, e), sk);
|
||||
|
||||
this.assertCount++;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the specified input param equals another param.
|
||||
*
|
||||
* @param {Object} v1 Object/item to check.
|
||||
* @param {Object} v2 Object/item to check.
|
||||
* @param {String} m Optional message to output.
|
||||
* @param {bool} sk Skip error output if this is true.
|
||||
*/
|
||||
eq : function(v1, v2, m, sk) {
|
||||
this.stats.asserts++;
|
||||
|
||||
if (v1 !== v2)
|
||||
this.fail(this.format(m || '[%d] Assert failed, values are not equal: was "%s", expected "%s"', this.assertCount, '' + v1, '' + v2), sk);
|
||||
|
||||
this.assertCount++;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the specified input param unequal to the other param.
|
||||
*
|
||||
* @param {Object} v1 Object/item to check.
|
||||
* @param {Object} v2 Object/item to check.
|
||||
* @param {String} m Optional message to output.
|
||||
* @param {bool} sk Skip error output if this is true.
|
||||
*/
|
||||
neq : function(v1, v2, m, sk) {
|
||||
this.stats.asserts++;
|
||||
|
||||
if (v1 == v2)
|
||||
this.fail(this.format(m || '[%d] Assert failed, values are equal: %s, %s', this.assertCount, v1, v2), sk);
|
||||
|
||||
this.assertCount++;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a failure message to the log.
|
||||
*
|
||||
* @param {String} m Message to output.
|
||||
* @param {bool} sk Skip error output if this is true.
|
||||
*/
|
||||
fail : function(m, sk) {
|
||||
var t = this;
|
||||
|
||||
if (sk) {
|
||||
t.stats.skipped_asserts++;
|
||||
if (t.settings.log_skipped)
|
||||
t.log('Skipped: ' + m);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
t.stats.failed_asserts++;
|
||||
t.failedTest = 1;
|
||||
t.logFailure(m);
|
||||
},
|
||||
|
||||
/**
|
||||
* Logs a failure message.
|
||||
*
|
||||
* @param {string} .. Things to log.
|
||||
*/
|
||||
logFailure : function() {
|
||||
var t = this;
|
||||
|
||||
DOM.add(DOM.get(t.id), 'div', {'class' : 'failure'}, DOM.encode(Array.prototype.join.call(arguments, ',')));
|
||||
|
||||
if (window.console && window.console.debug)
|
||||
console.debug(arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Logs a message.
|
||||
*
|
||||
* @param {string} .. Things to log.
|
||||
*/
|
||||
log : function() {
|
||||
DOM.add(DOM.get(this.id), 'div', null, DOM.encode(Array.prototype.join.call(arguments, ',')).replace(/\r?\n/g, '<br />'));
|
||||
},
|
||||
|
||||
/**
|
||||
* Logs a success message.
|
||||
*
|
||||
* @param {string} .. Things to log.
|
||||
*/
|
||||
logSuccess : function() {
|
||||
DOM.add(DOM.get(this.id), 'div', {'class' : 'success'}, DOM.encode(Array.prototype.join.call(arguments, ',')));
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
});
|
||||
})();
|
||||
+7
-10
@@ -1,24 +1,21 @@
|
||||
/**
|
||||
* $Id: XHR.js 832 2008-05-02 11:01:57Z spocke $
|
||||
* $Id: XHR.js 1194 2009-08-15 14:57:34Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* @class This class enables you to send XMLHTTPRequests cross browser.
|
||||
* @member tinymce.util.XHR
|
||||
/**
|
||||
* This class enables you to send XMLHTTPRequests cross browser.
|
||||
* @class tinymce.util.XHR
|
||||
* @static
|
||||
*/
|
||||
tinymce.create('static tinymce.util.XHR', {
|
||||
/**#@+
|
||||
* @method
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sends a XMLHTTPRequest.
|
||||
* Consult the Wiki for details on what settings this method takes.
|
||||
*
|
||||
* @method send
|
||||
* @param {Object} o Object will target URL, callbacks and other info needed to make the request.
|
||||
*/
|
||||
send : function(o) {
|
||||
@@ -53,6 +50,8 @@ tinymce.create('static tinymce.util.XHR', {
|
||||
if (o.content_type)
|
||||
x.setRequestHeader('Content-Type', o.content_type);
|
||||
|
||||
x.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
||||
|
||||
x.send(o.data);
|
||||
|
||||
function ready() {
|
||||
@@ -74,7 +73,5 @@ tinymce.create('static tinymce.util.XHR', {
|
||||
// Wait for response, onReadyStateChange can not be used since it leaks memory in IE
|
||||
t = w.setTimeout(ready, 10);
|
||||
}
|
||||
|
||||
/**#@-*/
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
(function(b){var c,a=[];function e(g,f,i){var h;h=b.fn[f];b.fn[f]=function(){var j;if(g!=="after"){j=i.apply(this,arguments);if(j!==undefined){return j}}j=h.apply(this,arguments);if(g!=="before"){i.apply(this,arguments)}return j}}b.fn.tinymce=function(i){var h=this,g,j="",f;if(!h.length){return}if(!i){return tinyMCE.get(this[0].id)}function k(){if(d){d();d=null}h.each(function(m,p){var l,o=p.id||tinymce.DOM.uniqueId();p.id=o;l=new tinymce.Editor(o,i);l.render()})}if(!window.tinymce&&!c&&(g=i.script_url)){c=1;if(/_(src|dev)\.js/g.test(g)){j="_src"}window.tinyMCEPreInit={base:g.substring(0,g.lastIndexOf("/")),suffix:j,query:""};b.getScript(g,function(){tinymce.dom.Event.domLoaded=1;c=2;k();b.each(a,function(l,m){m()})})}else{if(c===1){a.push(k)}else{k()}}};b.extend(b.expr[":"],{tinymce:function(f){return f.id&&!!tinyMCE.get(f.id)}});function d(){function f(){this.find("span.mceEditor,div.mceEditor").each(function(j,k){var h;if(h=tinyMCE.get(k.id.replace(/_parent$/,""))){h.remove()}})}function g(i){var h;if(i!==undefined){f.call(this);this.each(function(k,l){var j;if(j=tinyMCE.get(l.id)){j.setContent(i)}})}else{if(this.length>0){if(h=tinyMCE.get(this[0].id)){return h.getContent()}}}}e("both","text",function(h){if(h!==undefined){return g.call(this,h)}if(this.length>0){if(ed=tinyMCE.get(this[0].id)){return ed.getContent().replace(/<[^>]+>/g,"")}}});b.each(["val","html"],function(j,h){e("both",h,g)});b.each(["append","prepend"],function(j,h){e("before",h,function(i){if(i!==undefined){this.each(function(l,m){var k;if(k=tinyMCE.get(m.id)){if(h==="append"){k.setContent(k.getContent()+i)}else{k.setContent(i+k.getContent())}}})}})});e("both","attr",function(h,i){if(h&&h==="value"){return g.call(this,i)}});b.each(["remove","replaceWith","replaceAll","empty"],function(j,h){e("before",h,f)})}})(jQuery);
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.AdvancedHRPlugin',{init:function(ed,url){ed.addCommand('mceAdvancedHr',function(){ed.windowManager.open({file:url+'/rule.htm',width:250+parseInt(ed.getLang('advhr.delta_width',0)),height:160+parseInt(ed.getLang('advhr.delta_height',0)),inline:1},{plugin_url:url});});ed.addButton('advhr',{title:'advhr.advhr_desc',cmd:'mceAdvancedHr'});ed.onNodeChange.add(function(ed,cm,n){cm.setActive('advhr',n.nodeName=='HR');});ed.onClick.add(function(ed,e){e=e.target;if(e.nodeName==='HR')ed.selection.select(e);});},getInfo:function(){return{longname:'Advanced HR',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advhr',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('advhr',tinymce.plugins.AdvancedHRPlugin);})();
|
||||
(function(){tinymce.create("tinymce.plugins.AdvancedHRPlugin",{init:function(a,b){a.addCommand("mceAdvancedHr",function(){a.windowManager.open({file:b+"/rule.htm",width:250+parseInt(a.getLang("advhr.delta_width",0)),height:160+parseInt(a.getLang("advhr.delta_height",0)),inline:1},{plugin_url:b})});a.addButton("advhr",{title:"advhr.advhr_desc",cmd:"mceAdvancedHr"});a.onNodeChange.add(function(d,c,e){c.setActive("advhr",e.nodeName=="HR")});a.onClick.add(function(c,d){d=d.target;if(d.nodeName==="HR"){c.selection.select(d)}})},getInfo:function(){return{longname:"Advanced HR",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advhr",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("advhr",tinymce.plugins.AdvancedHRPlugin)})();
|
||||
+1
-2
@@ -7,7 +7,6 @@
|
||||
<script type="text/javascript" src="../../utils/mctabs.js"></script>
|
||||
<script type="text/javascript" src="../../utils/form_utils.js"></script>
|
||||
<link href="css/advhr.css" rel="stylesheet" type="text/css" />
|
||||
<base target="_self" />
|
||||
</head>
|
||||
<body>
|
||||
<form onsubmit="AdvHRDialog.update();return false;" action="#">
|
||||
@@ -22,7 +21,7 @@
|
||||
<table border="0" cellpadding="4" cellspacing="0">
|
||||
<tr>
|
||||
<td><label for="width">{#advhr_dlg.width}</label></td>
|
||||
<td nowrap="nowrap">
|
||||
<td class="nowrap">
|
||||
<input id="width" name="width" type="text" value="" class="mceFocus" />
|
||||
<select name="width2" id="width2">
|
||||
<option value="">px</option>
|
||||
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.AdvancedImagePlugin',{init:function(ed,url){ed.addCommand('mceAdvImage',function(){if(ed.dom.getAttrib(ed.selection.getNode(),'class').indexOf('mceItem')!=-1)return;ed.windowManager.open({file:url+'/image.htm',width:480+parseInt(ed.getLang('advimage.delta_width',0)),height:385+parseInt(ed.getLang('advimage.delta_height',0)),inline:1},{plugin_url:url});});ed.addButton('image',{title:'advimage.image_desc',cmd:'mceAdvImage'});},getInfo:function(){return{longname:'Advanced image',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advimage',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('advimage',tinymce.plugins.AdvancedImagePlugin);})();
|
||||
(function(){tinymce.create("tinymce.plugins.AdvancedImagePlugin",{init:function(a,b){a.addCommand("mceAdvImage",function(){if(a.dom.getAttrib(a.selection.getNode(),"class").indexOf("mceItem")!=-1){return}a.windowManager.open({file:b+"/image.htm",width:480+parseInt(a.getLang("advimage.delta_width",0)),height:385+parseInt(a.getLang("advimage.delta_height",0)),inline:1},{plugin_url:b})});a.addButton("image",{title:"advimage.image_desc",cmd:"mceAdvImage"})},getInfo:function(){return{longname:"Advanced image",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advimage",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("advimage",tinymce.plugins.AdvancedImagePlugin)})();
|
||||
+5
-6
@@ -9,7 +9,6 @@
|
||||
<script type="text/javascript" src="../../utils/editable_selects.js"></script>
|
||||
<script type="text/javascript" src="js/image.js"></script>
|
||||
<link href="css/advimage.css" rel="stylesheet" type="text/css" />
|
||||
<base target="_self" />
|
||||
</head>
|
||||
<body id="advimage" style="display: none">
|
||||
<form onsubmit="ImageDialog.insert();return false;" action="#">
|
||||
@@ -38,7 +37,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="src_list">{#advimage_dlg.image_list}</label></td>
|
||||
<td><select id="src_list" name="src_list" onchange="document.getElementById('src').value=this.options[this.selectedIndex].value;document.getElementById('alt').value=this.options[this.selectedIndex].text;document.getElementById('title').value=this.options[this.selectedIndex].text;ImageDialog.showPreviewImage(this.options[this.selectedIndex].value);"></select></td>
|
||||
<td><select id="src_list" name="src_list" onchange="document.getElementById('src').value=this.options[this.selectedIndex].value;document.getElementById('alt').value=this.options[this.selectedIndex].text;document.getElementById('title').value=this.options[this.selectedIndex].text;ImageDialog.showPreviewImage(this.options[this.selectedIndex].value);"><option value=""></option></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column1"><label id="altlabel" for="alt">{#advimage_dlg.alt}</label></td>
|
||||
@@ -89,7 +88,7 @@
|
||||
|
||||
<tr>
|
||||
<td class="column1"><label id="widthlabel" for="width">{#advimage_dlg.dimensions}</label></td>
|
||||
<td nowrap="nowrap">
|
||||
<td class="nowrap">
|
||||
<input name="width" type="text" id="width" value="" size="5" maxlength="5" class="size" onchange="ImageDialog.changeHeight();" /> x
|
||||
<input name="height" type="text" id="height" value="" size="5" maxlength="5" class="size" onchange="ImageDialog.changeWidth();" /> px
|
||||
</td>
|
||||
@@ -123,7 +122,7 @@
|
||||
|
||||
<tr>
|
||||
<td><label for="class_list">{#class_name}</label></td>
|
||||
<td colspan="2"><select id="class_list" name="class_list" class="mceEditableSelect"></select></td>
|
||||
<td colspan="2"><select id="class_list" name="class_list" class="mceEditableSelect"><option value=""></option></select></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -158,7 +157,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="over_list">{#advimage_dlg.image_list}</label></td>
|
||||
<td><select id="over_list" name="over_list" onchange="document.getElementById('onmouseoversrc').value=this.options[this.selectedIndex].value;"></select></td>
|
||||
<td><select id="over_list" name="over_list" onchange="document.getElementById('onmouseoversrc').value=this.options[this.selectedIndex].value;"><option value=""></option></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column1"><label id="onmouseoutsrclabel" for="onmouseoutsrc">{#advimage_dlg.mouseout}</label></td>
|
||||
@@ -171,7 +170,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="out_list">{#advimage_dlg.image_list}</label></td>
|
||||
<td><select id="out_list" name="out_list" onchange="document.getElementById('onmouseoutsrc').value=this.options[this.selectedIndex].value;"></select></td>
|
||||
<td><select id="out_list" name="out_list" onchange="document.getElementById('onmouseoutsrc').value=this.options[this.selectedIndex].value;"><option value=""></option></select></td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
|
||||
@@ -272,6 +272,7 @@ var ImageDialog = {
|
||||
cl = tinyMCEPopup.editor.dom.getClasses();
|
||||
|
||||
if (cl.length > 0) {
|
||||
lst.options.length = 0;
|
||||
lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), '');
|
||||
|
||||
tinymce.each(cl, function(o) {
|
||||
@@ -285,6 +286,7 @@ var ImageDialog = {
|
||||
var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl;
|
||||
|
||||
l = window[l];
|
||||
lst.options.length = 0;
|
||||
|
||||
if (l && l.length > 0) {
|
||||
lst.options[lst.options.length] = new Option('', '');
|
||||
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.AdvancedLinkPlugin',{init:function(ed,url){this.editor=ed;ed.addCommand('mceAdvLink',function(){var se=ed.selection;if(se.isCollapsed()&&!ed.dom.getParent(se.getNode(),'A'))return;ed.windowManager.open({file:url+'/link.htm',width:480+parseInt(ed.getLang('advlink.delta_width',0)),height:400+parseInt(ed.getLang('advlink.delta_height',0)),inline:1},{plugin_url:url});});ed.addButton('link',{title:'advlink.link_desc',cmd:'mceAdvLink'});ed.addShortcut('ctrl+k','advlink.advlink_desc','mceAdvLink');ed.onNodeChange.add(function(ed,cm,n,co){cm.setDisabled('link',co&&n.nodeName!='A');cm.setActive('link',n.nodeName=='A'&&!n.name);});},getInfo:function(){return{longname:'Advanced link',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advlink',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('advlink',tinymce.plugins.AdvancedLinkPlugin);})();
|
||||
(function(){tinymce.create("tinymce.plugins.AdvancedLinkPlugin",{init:function(a,b){this.editor=a;a.addCommand("mceAdvLink",function(){var c=a.selection;if(c.isCollapsed()&&!a.dom.getParent(c.getNode(),"A")){return}a.windowManager.open({file:b+"/link.htm",width:480+parseInt(a.getLang("advlink.delta_width",0)),height:400+parseInt(a.getLang("advlink.delta_height",0)),inline:1},{plugin_url:b})});a.addButton("link",{title:"advlink.link_desc",cmd:"mceAdvLink"});a.addShortcut("ctrl+k","advlink.advlink_desc","mceAdvLink");a.onNodeChange.add(function(d,c,f,e){c.setDisabled("link",e&&f.nodeName!="A");c.setActive("link",f.nodeName=="A"&&!f.name)})},getInfo:function(){return{longname:"Advanced link",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advlink",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("advlink",tinymce.plugins.AdvancedLinkPlugin)})();
|
||||
@@ -116,7 +116,7 @@ function checkPrefix(n) {
|
||||
if (n.value && Validator.isEmail(n) && !/^\s*mailto:/i.test(n.value) && confirm(tinyMCEPopup.getLang('advlink_dlg.is_email')))
|
||||
n.value = 'mailto:' + n.value;
|
||||
|
||||
if (/^\s*www./i.test(n.value) && confirm(tinyMCEPopup.getLang('advlink_dlg.is_external')))
|
||||
if (/^\s*www\./i.test(n.value) && confirm(tinyMCEPopup.getLang('advlink_dlg.is_external')))
|
||||
n.value = 'http://' + n.value;
|
||||
}
|
||||
|
||||
@@ -402,6 +402,7 @@ function insertAction() {
|
||||
|
||||
// Create new anchor elements
|
||||
if (elm == null) {
|
||||
inst.getDoc().execCommand("unlink", false, null);
|
||||
tinyMCEPopup.execCommand("CreateLink", false, "#mce_temp_url#", {skip_undo : 1});
|
||||
|
||||
elementArray = tinymce.grep(inst.dom.select("a"), function(n) {return inst.dom.getAttrib(n, 'href') == '#mce_temp_url#';});
|
||||
|
||||
+20
-21
@@ -8,7 +8,6 @@
|
||||
<script type="text/javascript" src="../../utils/validate.js"></script>
|
||||
<script type="text/javascript" src="js/advlink.js"></script>
|
||||
<link href="css/advlink.css" rel="stylesheet" type="text/css" />
|
||||
<base target="_self" />
|
||||
</head>
|
||||
<body id="advlink" style="display: none">
|
||||
<form onsubmit="insertAction();return false;" action="#">
|
||||
@@ -28,7 +27,7 @@
|
||||
|
||||
<table border="0" cellpadding="4" cellspacing="0">
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label id="hreflabel" for="href">{#advlink_dlg.url}</label></td>
|
||||
<td class="nowrap"><label id="hreflabel" for="href">{#advlink_dlg.url}</label></td>
|
||||
<td><table border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td><input id="href" name="href" type="text" class="mceFocus" value="" onchange="selectByValue(this.form,'linklisthref',this.value);" /></td>
|
||||
@@ -38,25 +37,25 @@
|
||||
</tr>
|
||||
<tr id="linklisthrefrow">
|
||||
<td class="column1"><label for="linklisthref">{#advlink_dlg.list}</label></td>
|
||||
<td colspan="2" id="linklisthrefcontainer"> </td>
|
||||
<td colspan="2" id="linklisthrefcontainer"><select id="linklisthref"><option value=""></option></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column1"><label for="anchorlist">{#advlink_dlg.anchor_names}</label></td>
|
||||
<td colspan="2" id="anchorlistcontainer"> </td>
|
||||
<td colspan="2" id="anchorlistcontainer"><select id="anchorlist"><option value=""></option></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label id="targetlistlabel" for="targetlist">{#advlink_dlg.target}</label></td>
|
||||
<td id="targetlistcontainer"> </td>
|
||||
<td id="targetlistcontainer"><select id="targetlist"><option value=""></option></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label id="titlelabel" for="title">{#advlink_dlg.titlefield}</label></td>
|
||||
<td class="nowrap"><label id="titlelabel" for="title">{#advlink_dlg.titlefield}</label></td>
|
||||
<td><input id="title" name="title" type="text" value="" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label id="classlabel" for="classlist">{#class_name}</label></td>
|
||||
<td>
|
||||
<select id="classlist" name="classlist" onchange="changeClass();">
|
||||
<option value="" selected>{#not_set}</option>
|
||||
<option value="" selected="selected">{#not_set}</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -73,7 +72,7 @@
|
||||
|
||||
<table border="0" cellpadding="0" cellspacing="4">
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label for="popupurl">{#advlink_dlg.popup_url}</label> </td>
|
||||
<td class="nowrap"><label for="popupurl">{#advlink_dlg.popup_url}</label> </td>
|
||||
<td>
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
@@ -84,19 +83,19 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label for="popupname">{#advlink_dlg.popup_name}</label> </td>
|
||||
<td class="nowrap"><label for="popupname">{#advlink_dlg.popup_name}</label> </td>
|
||||
<td><input type="text" name="popupname" id="popupname" value="" onchange="buildOnClick();" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label>{#advlink_dlg.popup_size}</label> </td>
|
||||
<td nowrap="nowrap">
|
||||
<td class="nowrap"><label>{#advlink_dlg.popup_size}</label> </td>
|
||||
<td class="nowrap">
|
||||
<input type="text" id="popupwidth" name="popupwidth" value="" onchange="buildOnClick();" /> x
|
||||
<input type="text" id="popupheight" name="popupheight" value="" onchange="buildOnClick();" /> px
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap="nowrap" id="labelleft"><label>{#advlink_dlg.popup_position}</label> </td>
|
||||
<td nowrap="nowrap">
|
||||
<td class="nowrap" id="labelleft"><label>{#advlink_dlg.popup_position}</label> </td>
|
||||
<td class="nowrap">
|
||||
<input type="text" id="popupleft" name="popupleft" value="" onchange="buildOnClick();" /> /
|
||||
<input type="text" id="popuptop" name="popuptop" value="" onchange="buildOnClick();" /> (c /c = center)
|
||||
</td>
|
||||
@@ -109,27 +108,27 @@
|
||||
<table border="0" cellpadding="0" cellspacing="4">
|
||||
<tr>
|
||||
<td><input type="checkbox" id="popuplocation" name="popuplocation" class="checkbox" onchange="buildOnClick();" /></td>
|
||||
<td nowrap="nowrap"><label id="popuplocationlabel" for="popuplocation">{#advlink_dlg.popup_location}</label></td>
|
||||
<td class="nowrap"><label id="popuplocationlabel" for="popuplocation">{#advlink_dlg.popup_location}</label></td>
|
||||
<td><input type="checkbox" id="popupscrollbars" name="popupscrollbars" class="checkbox" onchange="buildOnClick();" /></td>
|
||||
<td nowrap="nowrap"><label id="popupscrollbarslabel" for="popupscrollbars">{#advlink_dlg.popup_scrollbars}</label></td>
|
||||
<td class="nowrap"><label id="popupscrollbarslabel" for="popupscrollbars">{#advlink_dlg.popup_scrollbars}</label></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" id="popupmenubar" name="popupmenubar" class="checkbox" onchange="buildOnClick();" /></td>
|
||||
<td nowrap="nowrap"><label id="popupmenubarlabel" for="popupmenubar">{#advlink_dlg.popup_menubar}</label></td>
|
||||
<td class="nowrap"><label id="popupmenubarlabel" for="popupmenubar">{#advlink_dlg.popup_menubar}</label></td>
|
||||
<td><input type="checkbox" id="popupresizable" name="popupresizable" class="checkbox" onchange="buildOnClick();" /></td>
|
||||
<td nowrap="nowrap"><label id="popupresizablelabel" for="popupresizable">{#advlink_dlg.popup_resizable}</label></td>
|
||||
<td class="nowrap"><label id="popupresizablelabel" for="popupresizable">{#advlink_dlg.popup_resizable}</label></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" id="popuptoolbar" name="popuptoolbar" class="checkbox" onchange="buildOnClick();" /></td>
|
||||
<td nowrap="nowrap"><label id="popuptoolbarlabel" for="popuptoolbar">{#advlink_dlg.popup_toolbar}</label></td>
|
||||
<td class="nowrap"><label id="popuptoolbarlabel" for="popuptoolbar">{#advlink_dlg.popup_toolbar}</label></td>
|
||||
<td><input type="checkbox" id="popupdependent" name="popupdependent" class="checkbox" onchange="buildOnClick();" /></td>
|
||||
<td nowrap="nowrap"><label id="popupdependentlabel" for="popupdependent">{#advlink_dlg.popup_dependent}</label></td>
|
||||
<td class="nowrap"><label id="popupdependentlabel" for="popupdependent">{#advlink_dlg.popup_dependent}</label></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" id="popupstatus" name="popupstatus" class="checkbox" onchange="buildOnClick();" /></td>
|
||||
<td nowrap="nowrap"><label id="popupstatuslabel" for="popupstatus">{#advlink_dlg.popup_statusbar}</label></td>
|
||||
<td class="nowrap"><label id="popupstatuslabel" for="popupstatus">{#advlink_dlg.popup_statusbar}</label></td>
|
||||
<td><input type="checkbox" id="popupreturn" name="popupreturn" class="checkbox" onchange="buildOnClick();" checked="checked" /></td>
|
||||
<td nowrap="nowrap"><label id="popupreturnlabel" for="popupreturn">{#advlink_dlg.popup_return}</label></td>
|
||||
<td class="nowrap"><label id="popupreturnlabel" for="popupreturn">{#advlink_dlg.popup_return}</label></td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
(function(){tinymce.create("tinymce.plugins.AutoResizePlugin",{init:function(a,c){var d=this;if(a.getParam("fullscreen_is_enabled")){return}function b(){var h=a.getDoc(),e=h.body,j=h.documentElement,g=tinymce.DOM,i=d.autoresize_min_height,f;f=tinymce.isIE?e.scrollHeight:j.offsetHeight;if(f>d.autoresize_min_height){i=f}g.setStyle(g.get(a.id+"_ifr"),"height",i+"px");if(d.throbbing){a.setProgressState(false);a.setProgressState(true)}}d.editor=a;d.autoresize_min_height=a.getElement().offsetHeight;a.onInit.add(function(f,e){f.setProgressState(true);d.throbbing=true;f.getBody().style.overflowY="hidden"});a.onChange.add(b);a.onSetContent.add(b);a.onPaste.add(b);a.onKeyUp.add(b);a.onPostRender.add(b);a.onLoadContent.add(function(f,e){b();setTimeout(function(){b();f.setProgressState(false);d.throbbing=false},1250)});a.addCommand("mceAutoResize",b)},getInfo:function(){return{longname:"Auto Resize",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autoresize",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("autoresize",tinymce.plugins.AutoResizePlugin)})();
|
||||
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* $Id: editor_plugin_src.js 539 2008-01-14 19:08:58Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
/**
|
||||
* Auto Resize
|
||||
*
|
||||
* This plugin automatically resizes the content area to fit its content height.
|
||||
* It will retain a minimum height, which is the height of the content area when
|
||||
* it's initialized.
|
||||
*/
|
||||
tinymce.create('tinymce.plugins.AutoResizePlugin', {
|
||||
/**
|
||||
* Initializes the plugin, this will be executed after the plugin has been created.
|
||||
* This call is done before the editor instance has finished it's initialization so use the onInit event
|
||||
* of the editor instance to intercept that event.
|
||||
*
|
||||
* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
|
||||
* @param {string} url Absolute URL to where the plugin is located.
|
||||
*/
|
||||
init : function(ed, url) {
|
||||
var t = this;
|
||||
|
||||
if (ed.getParam('fullscreen_is_enabled'))
|
||||
return;
|
||||
|
||||
/**
|
||||
* This method gets executed each time the editor needs to resize.
|
||||
*/
|
||||
function resize() {
|
||||
var d = ed.getDoc(), b = d.body, de = d.documentElement, DOM = tinymce.DOM, resizeHeight = t.autoresize_min_height, myHeight;
|
||||
|
||||
// Get height differently depending on the browser used
|
||||
myHeight = tinymce.isIE ? b.scrollHeight : de.offsetHeight;
|
||||
|
||||
// Don't make it smaller than the minimum height
|
||||
if (myHeight > t.autoresize_min_height)
|
||||
resizeHeight = myHeight;
|
||||
|
||||
// Resize content element
|
||||
DOM.setStyle(DOM.get(ed.id + '_ifr'), 'height', resizeHeight + 'px');
|
||||
|
||||
// if we're throbbing, we'll re-throb to match the new size
|
||||
if (t.throbbing) {
|
||||
ed.setProgressState(false);
|
||||
ed.setProgressState(true);
|
||||
}
|
||||
};
|
||||
|
||||
t.editor = ed;
|
||||
|
||||
// Define minimum height
|
||||
t.autoresize_min_height = ed.getElement().offsetHeight;
|
||||
|
||||
// Things to do when the editor is ready
|
||||
ed.onInit.add(function(ed, l) {
|
||||
// Show throbber until content area is resized properly
|
||||
ed.setProgressState(true);
|
||||
t.throbbing = true;
|
||||
|
||||
// Hide scrollbars
|
||||
ed.getBody().style.overflowY = "hidden";
|
||||
});
|
||||
|
||||
// Add appropriate listeners for resizing content area
|
||||
ed.onChange.add(resize);
|
||||
ed.onSetContent.add(resize);
|
||||
ed.onPaste.add(resize);
|
||||
ed.onKeyUp.add(resize);
|
||||
ed.onPostRender.add(resize);
|
||||
|
||||
ed.onLoadContent.add(function(ed, l) {
|
||||
resize();
|
||||
|
||||
// Because the content area resizes when its content CSS loads,
|
||||
// and we can't easily add a listener to its onload event,
|
||||
// we'll just trigger a resize after a short loading period
|
||||
setTimeout(function() {
|
||||
resize();
|
||||
|
||||
// Disable throbber
|
||||
ed.setProgressState(false);
|
||||
t.throbbing = false;
|
||||
}, 1250);
|
||||
});
|
||||
|
||||
// Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceExample');
|
||||
ed.addCommand('mceAutoResize', resize);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns information about the plugin as a name/value array.
|
||||
* The current keys are longname, author, authorurl, infourl and version.
|
||||
*
|
||||
* @return {Object} Name/value array containing information about the plugin.
|
||||
*/
|
||||
getInfo : function() {
|
||||
return {
|
||||
longname : 'Auto Resize',
|
||||
author : 'Moxiecode Systems AB',
|
||||
authorurl : 'http://tinymce.moxiecode.com',
|
||||
infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autoresize',
|
||||
version : tinymce.majorVersion + "." + tinymce.minorVersion
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Register plugin
|
||||
tinymce.PluginManager.add('autoresize', tinymce.plugins.AutoResizePlugin);
|
||||
})();
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.AutoSavePlugin',{init:function(ed,url){var t=this;t.editor=ed;window.onbeforeunload=tinymce.plugins.AutoSavePlugin._beforeUnloadHandler;},getInfo:function(){return{longname:'Auto save',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave',version:tinymce.majorVersion+"."+tinymce.minorVersion};},'static':{_beforeUnloadHandler:function(){var msg;tinymce.each(tinyMCE.editors,function(ed){if(ed.getParam("fullscreen_is_enabled"))return;if(ed.isDirty()){msg=ed.getLang("autosave.unload_msg");return false;}});return msg;}}});tinymce.PluginManager.add('autosave',tinymce.plugins.AutoSavePlugin);})();
|
||||
(function(){tinymce.create("tinymce.plugins.AutoSavePlugin",{init:function(a,b){var c=this;c.editor=a;window.onbeforeunload=tinymce.plugins.AutoSavePlugin._beforeUnloadHandler},getInfo:function(){return{longname:"Auto save",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave",version:tinymce.majorVersion+"."+tinymce.minorVersion}},"static":{_beforeUnloadHandler:function(){var a;tinymce.each(tinyMCE.editors,function(b){if(b.getParam("fullscreen_is_enabled")){return}if(b.isDirty()){a=b.getLang("autosave.unload_msg");return false}});return a}}});tinymce.PluginManager.add("autosave",tinymce.plugins.AutoSavePlugin)})();
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.BBCodePlugin',{init:function(ed,url){var t=this,dialect=ed.getParam('bbcode_dialect','punbb').toLowerCase();ed.onBeforeSetContent.add(function(ed,o){o.content=t['_'+dialect+'_bbcode2html'](o.content);});ed.onPostProcess.add(function(ed,o){if(o.set)o.content=t['_'+dialect+'_bbcode2html'](o.content);if(o.get)o.content=t['_'+dialect+'_html2bbcode'](o.content);});},getInfo:function(){return{longname:'BBCode Plugin',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/bbcode',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_punbb_html2bbcode:function(s){s=tinymce.trim(s);function rep(re,str){s=s.replace(re,str);};rep(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");rep(/<font.*?color=\"(.*?)\".*?class=\"codeStyle\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]");rep(/<font.*?color=\"(.*?)\".*?class=\"quoteStyle\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]");rep(/<font.*?class=\"codeStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]");rep(/<font.*?class=\"quoteStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]");rep(/<span style=\"color: ?(.*?);\">(.*?)<\/span>/gi,"[color=$1]$2[/color]");rep(/<font.*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[color=$1]$2[/color]");rep(/<span style=\"font-size:(.*?);\">(.*?)<\/span>/gi,"[size=$1]$2[/size]");rep(/<font>(.*?)<\/font>/gi,"$1");rep(/<img.*?src=\"(.*?)\".*?\/>/gi,"[img]$1[/img]");rep(/<span class=\"codeStyle\">(.*?)<\/span>/gi,"[code]$1[/code]");rep(/<span class=\"quoteStyle\">(.*?)<\/span>/gi,"[quote]$1[/quote]");rep(/<strong class=\"codeStyle\">(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]");rep(/<strong class=\"quoteStyle\">(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]");rep(/<em class=\"codeStyle\">(.*?)<\/em>/gi,"[code][i]$1[/i][/code]");rep(/<em class=\"quoteStyle\">(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]");rep(/<u class=\"codeStyle\">(.*?)<\/u>/gi,"[code][u]$1[/u][/code]");rep(/<u class=\"quoteStyle\">(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]");rep(/<\/(strong|b)>/gi,"[/b]");rep(/<(strong|b)>/gi,"[b]");rep(/<\/(em|i)>/gi,"[/i]");rep(/<(em|i)>/gi,"[i]");rep(/<\/u>/gi,"[/u]");rep(/<span style=\"text-decoration: ?underline;\">(.*?)<\/span>/gi,"[u]$1[/u]");rep(/<u>/gi,"[u]");rep(/<blockquote[^>]*>/gi,"[quote]");rep(/<\/blockquote>/gi,"[/quote]");rep(/<br \/>/gi,"\n");rep(/<br\/>/gi,"\n");rep(/<br>/gi,"\n");rep(/<p>/gi,"");rep(/<\/p>/gi,"\n");rep(/ /gi," ");rep(/"/gi,"\"");rep(/</gi,"<");rep(/>/gi,">");rep(/&/gi,"&");return s;},_punbb_bbcode2html:function(s){s=tinymce.trim(s);function rep(re,str){s=s.replace(re,str);};rep(/\n/gi,"<br />");rep(/\[b\]/gi,"<strong>");rep(/\[\/b\]/gi,"</strong>");rep(/\[i\]/gi,"<em>");rep(/\[\/i\]/gi,"</em>");rep(/\[u\]/gi,"<u>");rep(/\[\/u\]/gi,"</u>");rep(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,"<a href=\"$1\">$2</a>");rep(/\[url\](.*?)\[\/url\]/gi,"<a href=\"$1\">$1</a>");rep(/\[img\](.*?)\[\/img\]/gi,"<img src=\"$1\" />");rep(/\[color=(.*?)\](.*?)\[\/color\]/gi,"<font color=\"$1\">$2</font>");rep(/\[code\](.*?)\[\/code\]/gi,"<span class=\"codeStyle\">$1</span> ");rep(/\[quote.*?\](.*?)\[\/quote\]/gi,"<span class=\"quoteStyle\">$1</span> ");return s;}});tinymce.PluginManager.add('bbcode',tinymce.plugins.BBCodePlugin);})();
|
||||
(function(){tinymce.create("tinymce.plugins.BBCodePlugin",{init:function(a,b){var d=this,c=a.getParam("bbcode_dialect","punbb").toLowerCase();a.onBeforeSetContent.add(function(e,f){f.content=d["_"+c+"_bbcode2html"](f.content)});a.onPostProcess.add(function(e,f){if(f.set){f.content=d["_"+c+"_bbcode2html"](f.content)}if(f.get){f.content=d["_"+c+"_html2bbcode"](f.content)}})},getInfo:function(){return{longname:"BBCode Plugin",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/bbcode",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_punbb_html2bbcode:function(a){a=tinymce.trim(a);function b(c,d){a=a.replace(c,d)}b(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");b(/<font.*?color=\"(.*?)\".*?class=\"codeStyle\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]");b(/<font.*?color=\"(.*?)\".*?class=\"quoteStyle\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]");b(/<font.*?class=\"codeStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]");b(/<font.*?class=\"quoteStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]");b(/<span style=\"color: ?(.*?);\">(.*?)<\/span>/gi,"[color=$1]$2[/color]");b(/<font.*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[color=$1]$2[/color]");b(/<span style=\"font-size:(.*?);\">(.*?)<\/span>/gi,"[size=$1]$2[/size]");b(/<font>(.*?)<\/font>/gi,"$1");b(/<img.*?src=\"(.*?)\".*?\/>/gi,"[img]$1[/img]");b(/<span class=\"codeStyle\">(.*?)<\/span>/gi,"[code]$1[/code]");b(/<span class=\"quoteStyle\">(.*?)<\/span>/gi,"[quote]$1[/quote]");b(/<strong class=\"codeStyle\">(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]");b(/<strong class=\"quoteStyle\">(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]");b(/<em class=\"codeStyle\">(.*?)<\/em>/gi,"[code][i]$1[/i][/code]");b(/<em class=\"quoteStyle\">(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]");b(/<u class=\"codeStyle\">(.*?)<\/u>/gi,"[code][u]$1[/u][/code]");b(/<u class=\"quoteStyle\">(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]");b(/<\/(strong|b)>/gi,"[/b]");b(/<(strong|b)>/gi,"[b]");b(/<\/(em|i)>/gi,"[/i]");b(/<(em|i)>/gi,"[i]");b(/<\/u>/gi,"[/u]");b(/<span style=\"text-decoration: ?underline;\">(.*?)<\/span>/gi,"[u]$1[/u]");b(/<u>/gi,"[u]");b(/<blockquote[^>]*>/gi,"[quote]");b(/<\/blockquote>/gi,"[/quote]");b(/<br \/>/gi,"\n");b(/<br\/>/gi,"\n");b(/<br>/gi,"\n");b(/<p>/gi,"");b(/<\/p>/gi,"\n");b(/ /gi," ");b(/"/gi,'"');b(/</gi,"<");b(/>/gi,">");b(/&/gi,"&");return a},_punbb_bbcode2html:function(a){a=tinymce.trim(a);function b(c,d){a=a.replace(c,d)}b(/\n/gi,"<br />");b(/\[b\]/gi,"<strong>");b(/\[\/b\]/gi,"</strong>");b(/\[i\]/gi,"<em>");b(/\[\/i\]/gi,"</em>");b(/\[u\]/gi,"<u>");b(/\[\/u\]/gi,"</u>");b(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'<a href="$1">$2</a>');b(/\[url\](.*?)\[\/url\]/gi,'<a href="$1">$1</a>');b(/\[img\](.*?)\[\/img\]/gi,'<img src="$1" />');b(/\[color=(.*?)\](.*?)\[\/color\]/gi,'<font color="$1">$2</font>');b(/\[code\](.*?)\[\/code\]/gi,'<span class="codeStyle">$1</span> ');b(/\[quote.*?\](.*?)\[\/quote\]/gi,'<span class="quoteStyle">$1</span> ');return a}});tinymce.PluginManager.add("bbcode",tinymce.plugins.BBCodePlugin)})();
|
||||
@@ -1 +1 @@
|
||||
(function(){var Event=tinymce.dom.Event,each=tinymce.each,DOM=tinymce.DOM;tinymce.create('tinymce.plugins.ContextMenu',{init:function(ed){var t=this;t.editor=ed;t.onContextMenu=new tinymce.util.Dispatcher(this);ed.onContextMenu.add(function(ed,e){if(!e.ctrlKey){t._getMenu(ed).showMenu(e.clientX,e.clientY);Event.add(ed.getDoc(),'click',hide);Event.cancel(e);}});function hide(){if(t._menu){t._menu.removeAll();t._menu.destroy();Event.remove(ed.getDoc(),'click',hide);}};ed.onMouseDown.add(hide);ed.onKeyDown.add(hide);},getInfo:function(){return{longname:'Contextmenu',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/contextmenu',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_getMenu:function(ed){var t=this,m=t._menu,se=ed.selection,col=se.isCollapsed(),el=se.getNode()||ed.getBody(),am,p1,p2;if(m){m.removeAll();m.destroy();}p1=DOM.getPos(ed.getContentAreaContainer());p2=DOM.getPos(ed.getContainer());m=ed.controlManager.createDropMenu('contextmenu',{offset_x:p1.x+ed.getParam('contextmenu_offset_x',0),offset_y:p1.y+ed.getParam('contextmenu_offset_y',0),constrain:1});t._menu=m;m.add({title:'advanced.cut_desc',icon:'cut',cmd:'Cut'}).setDisabled(col);m.add({title:'advanced.copy_desc',icon:'copy',cmd:'Copy'}).setDisabled(col);m.add({title:'advanced.paste_desc',icon:'paste',cmd:'Paste'});if((el.nodeName=='A'&&!ed.dom.getAttrib(el,'name'))||!col){m.addSeparator();m.add({title:'advanced.link_desc',icon:'link',cmd:ed.plugins.advlink?'mceAdvLink':'mceLink',ui:true});m.add({title:'advanced.unlink_desc',icon:'unlink',cmd:'UnLink'});}m.addSeparator();m.add({title:'advanced.image_desc',icon:'image',cmd:ed.plugins.advimage?'mceAdvImage':'mceImage',ui:true});m.addSeparator();am=m.addMenu({title:'contextmenu.align'});am.add({title:'contextmenu.left',icon:'justifyleft',cmd:'JustifyLeft'});am.add({title:'contextmenu.center',icon:'justifycenter',cmd:'JustifyCenter'});am.add({title:'contextmenu.right',icon:'justifyright',cmd:'JustifyRight'});am.add({title:'contextmenu.full',icon:'justifyfull',cmd:'JustifyFull'});t.onContextMenu.dispatch(t,m,el,col);return m;}});tinymce.PluginManager.add('contextmenu',tinymce.plugins.ContextMenu);})();
|
||||
(function(){var a=tinymce.dom.Event,c=tinymce.each,b=tinymce.DOM;tinymce.create("tinymce.plugins.ContextMenu",{init:function(d){var f=this;f.editor=d;f.onContextMenu=new tinymce.util.Dispatcher(this);d.onContextMenu.add(function(g,h){if(!h.ctrlKey){f._getMenu(g).showMenu(h.clientX,h.clientY);a.add(g.getDoc(),"click",e);a.cancel(h)}});function e(){if(f._menu){f._menu.removeAll();f._menu.destroy();a.remove(d.getDoc(),"click",e)}}d.onMouseDown.add(e);d.onKeyDown.add(e)},getInfo:function(){return{longname:"Contextmenu",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/contextmenu",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_getMenu:function(h){var l=this,f=l._menu,i=h.selection,e=i.isCollapsed(),d=i.getNode()||h.getBody(),g,k,j;if(f){f.removeAll();f.destroy()}k=b.getPos(h.getContentAreaContainer());j=b.getPos(h.getContainer());f=h.controlManager.createDropMenu("contextmenu",{offset_x:k.x+h.getParam("contextmenu_offset_x",0),offset_y:k.y+h.getParam("contextmenu_offset_y",0),constrain:1});l._menu=f;f.add({title:"advanced.cut_desc",icon:"cut",cmd:"Cut"}).setDisabled(e);f.add({title:"advanced.copy_desc",icon:"copy",cmd:"Copy"}).setDisabled(e);f.add({title:"advanced.paste_desc",icon:"paste",cmd:"Paste"});if((d.nodeName=="A"&&!h.dom.getAttrib(d,"name"))||!e){f.addSeparator();f.add({title:"advanced.link_desc",icon:"link",cmd:h.plugins.advlink?"mceAdvLink":"mceLink",ui:true});f.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"})}f.addSeparator();f.add({title:"advanced.image_desc",icon:"image",cmd:h.plugins.advimage?"mceAdvImage":"mceImage",ui:true});f.addSeparator();g=f.addMenu({title:"contextmenu.align"});g.add({title:"contextmenu.left",icon:"justifyleft",cmd:"JustifyLeft"});g.add({title:"contextmenu.center",icon:"justifycenter",cmd:"JustifyCenter"});g.add({title:"contextmenu.right",icon:"justifyright",cmd:"JustifyRight"});g.add({title:"contextmenu.full",icon:"justifyfull",cmd:"JustifyFull"});l.onContextMenu.dispatch(l,f,d,e);return f}});tinymce.PluginManager.add("contextmenu",tinymce.plugins.ContextMenu)})();
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.Directionality',{init:function(ed,url){var t=this;t.editor=ed;ed.addCommand('mceDirectionLTR',function(){var e=ed.dom.getParent(ed.selection.getNode(),ed.dom.isBlock);if(e){if(ed.dom.getAttrib(e,"dir")!="ltr")ed.dom.setAttrib(e,"dir","ltr");else ed.dom.setAttrib(e,"dir","");}ed.nodeChanged();});ed.addCommand('mceDirectionRTL',function(){var e=ed.dom.getParent(ed.selection.getNode(),ed.dom.isBlock);if(e){if(ed.dom.getAttrib(e,"dir")!="rtl")ed.dom.setAttrib(e,"dir","rtl");else ed.dom.setAttrib(e,"dir","");}ed.nodeChanged();});ed.addButton('ltr',{title:'directionality.ltr_desc',cmd:'mceDirectionLTR'});ed.addButton('rtl',{title:'directionality.rtl_desc',cmd:'mceDirectionRTL'});ed.onNodeChange.add(t._nodeChange,t);},getInfo:function(){return{longname:'Directionality',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_nodeChange:function(ed,cm,n){var dom=ed.dom,dir;n=dom.getParent(n,dom.isBlock);if(!n){cm.setDisabled('ltr',1);cm.setDisabled('rtl',1);return;}dir=dom.getAttrib(n,'dir');cm.setActive('ltr',dir=="ltr");cm.setDisabled('ltr',0);cm.setActive('rtl',dir=="rtl");cm.setDisabled('rtl',0);}});tinymce.PluginManager.add('directionality',tinymce.plugins.Directionality);})();
|
||||
(function(){tinymce.create("tinymce.plugins.Directionality",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceDirectionLTR",function(){var d=a.dom.getParent(a.selection.getNode(),a.dom.isBlock);if(d){if(a.dom.getAttrib(d,"dir")!="ltr"){a.dom.setAttrib(d,"dir","ltr")}else{a.dom.setAttrib(d,"dir","")}}a.nodeChanged()});a.addCommand("mceDirectionRTL",function(){var d=a.dom.getParent(a.selection.getNode(),a.dom.isBlock);if(d){if(a.dom.getAttrib(d,"dir")!="rtl"){a.dom.setAttrib(d,"dir","rtl")}else{a.dom.setAttrib(d,"dir","")}}a.nodeChanged()});a.addButton("ltr",{title:"directionality.ltr_desc",cmd:"mceDirectionLTR"});a.addButton("rtl",{title:"directionality.rtl_desc",cmd:"mceDirectionRTL"});a.onNodeChange.add(c._nodeChange,c)},getInfo:function(){return{longname:"Directionality",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_nodeChange:function(b,a,e){var d=b.dom,c;e=d.getParent(e,d.isBlock);if(!e){a.setDisabled("ltr",1);a.setDisabled("rtl",1);return}c=d.getAttrib(e,"dir");a.setActive("ltr",c=="ltr");a.setDisabled("ltr",0);a.setActive("rtl",c=="rtl");a.setDisabled("rtl",0)}});tinymce.PluginManager.add("directionality",tinymce.plugins.Directionality)})();
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.EmotionsPlugin',{init:function(ed,url){ed.addCommand('mceEmotion',function(){ed.windowManager.open({file:url+'/emotions.htm',width:250+parseInt(ed.getLang('emotions.delta_width',0)),height:160+parseInt(ed.getLang('emotions.delta_height',0)),inline:1},{plugin_url:url});});ed.addButton('emotions',{title:'emotions.emotions_desc',cmd:'mceEmotion'});},getInfo:function(){return{longname:'Emotions',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/emotions',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('emotions',tinymce.plugins.EmotionsPlugin);})();
|
||||
(function(){tinymce.create("tinymce.plugins.EmotionsPlugin",{init:function(a,b){a.addCommand("mceEmotion",function(){a.windowManager.open({file:b+"/emotions.htm",width:250+parseInt(a.getLang("emotions.delta_width",0)),height:160+parseInt(a.getLang("emotions.delta_height",0)),inline:1},{plugin_url:b})});a.addButton("emotions",{title:"emotions.emotions_desc",cmd:"mceEmotion"})},getInfo:function(){return{longname:"Emotions",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/emotions",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("emotions",tinymce.plugins.EmotionsPlugin)})();
|
||||
@@ -1,10 +1,9 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>{#emotions_dlg.title}</title>
|
||||
<script type="text/javascript" src="../../tiny_mce_popup.js"></script>
|
||||
<script type="text/javascript" src="js/emotions.js"></script>
|
||||
<base target="_self" />
|
||||
</head>
|
||||
<body style="display: none">
|
||||
<div align="center">
|
||||
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.PluginManager.requireLangPack('example');tinymce.create('tinymce.plugins.ExamplePlugin',{init:function(ed,url){ed.addCommand('mceExample',function(){ed.windowManager.open({file:url+'/dialog.htm',width:320+parseInt(ed.getLang('example.delta_width',0)),height:120+parseInt(ed.getLang('example.delta_height',0)),inline:1},{plugin_url:url,some_custom_arg:'custom arg'});});ed.addButton('example',{title:'example.desc',cmd:'mceExample',image:url+'/img/example.gif'});ed.onNodeChange.add(function(ed,cm,n){cm.setActive('example',n.nodeName=='IMG');});},createControl:function(n,cm){return null;},getInfo:function(){return{longname:'Example plugin',author:'Some author',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/example',version:"1.0"};}});tinymce.PluginManager.add('example',tinymce.plugins.ExamplePlugin);})();
|
||||
(function(){tinymce.PluginManager.requireLangPack("example");tinymce.create("tinymce.plugins.ExamplePlugin",{init:function(a,b){a.addCommand("mceExample",function(){a.windowManager.open({file:b+"/dialog.htm",width:320+parseInt(a.getLang("example.delta_width",0)),height:120+parseInt(a.getLang("example.delta_height",0)),inline:1},{plugin_url:b,some_custom_arg:"custom arg"})});a.addButton("example",{title:"example.desc",cmd:"mceExample",image:b+"/img/example.gif"});a.onNodeChange.add(function(d,c,e){c.setActive("example",e.nodeName=="IMG")})},createControl:function(b,a){return null},getInfo:function(){return{longname:"Example plugin",author:"Some author",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/example",version:"1.0"}}});tinymce.PluginManager.add("example",tinymce.plugins.ExamplePlugin)})();
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.FullPagePlugin',{init:function(ed,url){var t=this;t.editor=ed;ed.addCommand('mceFullPageProperties',function(){ed.windowManager.open({file:url+'/fullpage.htm',width:430+parseInt(ed.getLang('fullpage.delta_width',0)),height:495+parseInt(ed.getLang('fullpage.delta_height',0)),inline:1},{plugin_url:url,head_html:t.head});});ed.addButton('fullpage',{title:'fullpage.desc',cmd:'mceFullPageProperties'});ed.onBeforeSetContent.add(t._setContent,t);ed.onSetContent.add(t._setBodyAttribs,t);ed.onGetContent.add(t._getContent,t);},getInfo:function(){return{longname:'Fullpage',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullpage',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_setBodyAttribs:function(ed,o){var bdattr,i,len,kv,k,v,t,attr=this.head.match(/body(.*?)>/i);if(attr&&attr[1]){bdattr=attr[1].match(/\s*(\w+\s*=\s*".*?"|\w+\s*=\s*'.*?'|\w+\s*=\s*\w+|\w+)\s*/g);if(bdattr){for(i=0,len=bdattr.length;i<len;i++){kv=bdattr[i].split('=');k=kv[0].replace(/\s/,'');v=kv[1];if(v){v=v.replace(/^\s+/,'').replace(/\s+$/,'');t=v.match(/^["'](.*)["']$/);if(t)v=t[1];}else v=k;ed.dom.setAttrib(ed.getBody(),'style',v);}}}},_createSerializer:function(){return new tinymce.dom.Serializer({dom:this.editor.dom,apply_source_formatting:true});},_setContent:function(ed,o){var t=this,sp,ep,c=o.content,v,st='';c=c.replace(/<(\/?)BODY/gi,'<$1body');sp=c.indexOf('<body');if(sp!=-1){sp=c.indexOf('>',sp);t.head=c.substring(0,sp+1);ep=c.indexOf('</body',sp);if(ep==-1)ep=c.indexOf('</body',ep);o.content=c.substring(sp+1,ep);t.foot=c.substring(ep);function low(s){return s.replace(/<\/?[A-Z]+/g,function(a){return a.toLowerCase();})};t.head=low(t.head);t.foot=low(t.foot);}else{t.head='';if(ed.getParam('fullpage_default_xml_pi'))t.head+='<?xml version="1.0" encoding="'+ed.getParam('fullpage_default_encoding','ISO-8859-1')+'" ?>\n';t.head+=ed.getParam('fullpage_default_doctype','<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">');t.head+='\n<html>\n<head>\n<title>'+ed.getParam('fullpage_default_title','Untitled document')+'</title>\n';if(v=ed.getParam('fullpage_default_encoding'))t.head+='<meta http-equiv="Content-Type" content="'+v+'" />\n';if(v=ed.getParam('fullpage_default_font_family'))st+='font-family: '+v+';';if(v=ed.getParam('fullpage_default_font_size'))st+='font-size: '+v+';';if(v=ed.getParam('fullpage_default_text_color'))st+='color: '+v+';';t.head+='</head>\n<body'+(st?' style="'+st+'"':'')+'>\n';t.foot='\n</body>\n</html>';}},_getContent:function(ed,o){var t=this;o.content=tinymce.trim(t.head)+'\n'+tinymce.trim(o.content)+'\n'+tinymce.trim(t.foot);}});tinymce.PluginManager.add('fullpage',tinymce.plugins.FullPagePlugin);})();
|
||||
(function(){tinymce.create("tinymce.plugins.FullPagePlugin",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceFullPageProperties",function(){a.windowManager.open({file:b+"/fullpage.htm",width:430+parseInt(a.getLang("fullpage.delta_width",0)),height:495+parseInt(a.getLang("fullpage.delta_height",0)),inline:1},{plugin_url:b,head_html:c.head})});a.addButton("fullpage",{title:"fullpage.desc",cmd:"mceFullPageProperties"});a.onBeforeSetContent.add(c._setContent,c);a.onSetContent.add(c._setBodyAttribs,c);a.onGetContent.add(c._getContent,c)},getInfo:function(){return{longname:"Fullpage",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullpage",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_setBodyAttribs:function(d,a){var l,c,e,g,b,h,j,f=this.head.match(/body(.*?)>/i);if(f&&f[1]){l=f[1].match(/\s*(\w+\s*=\s*".*?"|\w+\s*=\s*'.*?'|\w+\s*=\s*\w+|\w+)\s*/g);if(l){for(c=0,e=l.length;c<e;c++){g=l[c].split("=");b=g[0].replace(/\s/,"");h=g[1];if(h){h=h.replace(/^\s+/,"").replace(/\s+$/,"");j=h.match(/^["'](.*)["']$/);if(j){h=j[1]}}else{h=b}d.dom.setAttrib(d.getBody(),"style",h)}}}},_createSerializer:function(){return new tinymce.dom.Serializer({dom:this.editor.dom,apply_source_formatting:true})},_setContent:function(d,b){var h=this,a,j,f=b.content,g,i="";if(b.source_view&&d.getParam("fullpage_hide_in_source_view")){return}f=f.replace(/<(\/?)BODY/gi,"<$1body");a=f.indexOf("<body");if(a!=-1){a=f.indexOf(">",a);h.head=f.substring(0,a+1);j=f.indexOf("</body",a);if(j==-1){j=f.indexOf("</body",j)}b.content=f.substring(a+1,j);h.foot=f.substring(j);function e(c){return c.replace(/<\/?[A-Z]+/g,function(k){return k.toLowerCase()})}h.head=e(h.head);h.foot=e(h.foot)}else{h.head="";if(d.getParam("fullpage_default_xml_pi")){h.head+='<?xml version="1.0" encoding="'+d.getParam("fullpage_default_encoding","ISO-8859-1")+'" ?>\n'}h.head+=d.getParam("fullpage_default_doctype",'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">');h.head+="\n<html>\n<head>\n<title>"+d.getParam("fullpage_default_title","Untitled document")+"</title>\n";if(g=d.getParam("fullpage_default_encoding")){h.head+='<meta http-equiv="Content-Type" content="'+g+'" />\n'}if(g=d.getParam("fullpage_default_font_family")){i+="font-family: "+g+";"}if(g=d.getParam("fullpage_default_font_size")){i+="font-size: "+g+";"}if(g=d.getParam("fullpage_default_text_color")){i+="color: "+g+";"}h.head+="</head>\n<body"+(i?' style="'+i+'"':"")+">\n";h.foot="\n</body>\n</html>"}},_getContent:function(a,c){var b=this;if(!c.source_view||!a.getParam("fullpage_hide_in_source_view")){c.content=tinymce.trim(b.head)+"\n"+tinymce.trim(c.content)+"\n"+tinymce.trim(b.foot)}}});tinymce.PluginManager.add("fullpage",tinymce.plugins.FullPagePlugin)})();
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: editor_plugin_src.js 920 2008-09-09 14:05:33Z spocke $
|
||||
* $Id: editor_plugin_src.js 1029 2009-02-24 22:32:21Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
@@ -82,6 +82,9 @@
|
||||
_setContent : function(ed, o) {
|
||||
var t = this, sp, ep, c = o.content, v, st = '';
|
||||
|
||||
if (o.source_view && ed.getParam('fullpage_hide_in_source_view'))
|
||||
return;
|
||||
|
||||
// Parse out head, body and footer
|
||||
c = c.replace(/<(\/?)BODY/gi, '<$1body');
|
||||
sp = c.indexOf('<body');
|
||||
@@ -133,7 +136,8 @@
|
||||
_getContent : function(ed, o) {
|
||||
var t = this;
|
||||
|
||||
o.content = tinymce.trim(t.head) + '\n' + tinymce.trim(o.content) + '\n' + tinymce.trim(t.foot);
|
||||
if (!o.source_view || !ed.getParam('fullpage_hide_in_source_view'))
|
||||
o.content = tinymce.trim(t.head) + '\n' + tinymce.trim(o.content) + '\n' + tinymce.trim(t.foot);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+9
-10
@@ -7,7 +7,6 @@
|
||||
<script type="text/javascript" src="../../utils/form_utils.js"></script>
|
||||
<script type="text/javascript" src="js/fullpage.js"></script>
|
||||
<link href="css/fullpage.css" rel="stylesheet" type="text/css" />
|
||||
<base target="_self" />
|
||||
</head>
|
||||
<body id="advlink" style="display: none">
|
||||
<form onsubmit="updateAction();return false;" name="fullpage" action="#">
|
||||
@@ -26,27 +25,27 @@
|
||||
|
||||
<table border="0" cellpadding="4" cellspacing="0">
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label for="metatitle">{#fullpage_dlg.meta_title}</label> </td>
|
||||
<td class="nowrap"><label for="metatitle">{#fullpage_dlg.meta_title}</label> </td>
|
||||
<td><input type="text" id="metatitle" name="metatitle" value="" class="mceFocus" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label for="metakeywords">{#fullpage_dlg.meta_keywords}</label> </td>
|
||||
<td class="nowrap"><label for="metakeywords">{#fullpage_dlg.meta_keywords}</label> </td>
|
||||
<td><textarea id="metakeywords" name="metakeywords" rows="4"></textarea></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label for="metadescription">{#fullpage_dlg.meta_description}</label> </td>
|
||||
<td class="nowrap"><label for="metadescription">{#fullpage_dlg.meta_description}</label> </td>
|
||||
<td><textarea id="metadescription" name="metadescription" rows="4"></textarea></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label for="metaauthor">{#fullpage_dlg.author}</label> </td>
|
||||
<td class="nowrap"><label for="metaauthor">{#fullpage_dlg.author}</label> </td>
|
||||
<td><input type="text" id="metaauthor" name="metaauthor" value="" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label for="metacopyright">{#fullpage_dlg.copyright}</label> </td>
|
||||
<td class="nowrap"><label for="metacopyright">{#fullpage_dlg.copyright}</label> </td>
|
||||
<td><input type="text" id="metacopyright" name="metacopyright" value="" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label for="metarobots">{#fullpage_dlg.meta_robots}</label> </td>
|
||||
<td class="nowrap"><label for="metarobots">{#fullpage_dlg.meta_robots}</label> </td>
|
||||
<td>
|
||||
<select id="metarobots" name="metarobots">
|
||||
<option value="">{#not_set}</option>
|
||||
@@ -73,7 +72,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label for="doctypes">{#fullpage_dlg.doctypes}</label> </td>
|
||||
<td class="nowrap"><label for="doctypes">{#fullpage_dlg.doctypes}</label> </td>
|
||||
<td>
|
||||
<select id="doctypes" name="doctypes">
|
||||
<option value="">{#not_set}</option>
|
||||
@@ -81,7 +80,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label for="langcode">{#fullpage_dlg.langcode}</label> </td>
|
||||
<td class="nowrap"><label for="langcode">{#fullpage_dlg.langcode}</label> </td>
|
||||
<td><input type="text" id="langcode" name="langcode" value="" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -95,7 +94,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap="nowrap"><label for="xml_pi">{#fullpage_dlg.xml_pi}</label> </td>
|
||||
<td class="nowrap"><label for="xml_pi">{#fullpage_dlg.xml_pi}</label> </td>
|
||||
<td><input type="checkbox" id="xml_pi" name="xml_pi" class="checkbox" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -123,7 +123,7 @@ function init() {
|
||||
// Parse xml and doctype
|
||||
xmlVer = getReItem(/<\?\s*?xml.*?version\s*?=\s*?"(.*?)".*?\?>/gi, h, 1);
|
||||
xmlEnc = getReItem(/<\?\s*?xml.*?encoding\s*?=\s*?"(.*?)".*?\?>/gi, h, 1);
|
||||
docType = getReItem(/<\!DOCTYPE.*?>/gi, h, 0);
|
||||
docType = getReItem(/<\!DOCTYPE.*?>/gi, h.replace(/\n/g, ''), 0).replace(/ +/g, ' ');
|
||||
f.langcode.value = getReItem(/lang="(.*?)"/gi, h, 1);
|
||||
|
||||
// Parse title
|
||||
|
||||
@@ -1 +1 @@
|
||||
(function(){var DOM=tinymce.DOM;tinymce.create('tinymce.plugins.FullScreenPlugin',{init:function(ed,url){var t=this,s={},vp;t.editor=ed;ed.addCommand('mceFullScreen',function(){var win,de=DOM.doc.documentElement;if(ed.getParam('fullscreen_is_enabled')){if(ed.getParam('fullscreen_new_window'))closeFullscreen();else{DOM.win.setTimeout(function(){tinymce.dom.Event.remove(DOM.win,'resize',t.resizeFunc);tinyMCE.get(ed.getParam('fullscreen_editor_id')).setContent(ed.getContent({format:'raw'}),{format:'raw'});tinyMCE.remove(ed);DOM.remove('mce_fullscreen_container');de.style.overflow=ed.getParam('fullscreen_html_overflow');DOM.setStyle(DOM.doc.body,'overflow',ed.getParam('fullscreen_overflow'));DOM.win.scrollTo(ed.getParam('fullscreen_scrollx'),ed.getParam('fullscreen_scrolly'));tinyMCE.settings=tinyMCE.oldSettings;},10);}return;}if(ed.getParam('fullscreen_new_window')){win=DOM.win.open(url+"/fullscreen.htm","mceFullScreenPopup","fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width="+screen.availWidth+",height="+screen.availHeight);try{win.resizeTo(screen.availWidth,screen.availHeight);}catch(e){}}else{tinyMCE.oldSettings=tinyMCE.settings;s.fullscreen_overflow=DOM.getStyle(DOM.doc.body,'overflow',1)||'auto';s.fullscreen_html_overflow=DOM.getStyle(de,'overflow',1);vp=DOM.getViewPort();s.fullscreen_scrollx=vp.x;s.fullscreen_scrolly=vp.y;if(tinymce.isOpera&&s.fullscreen_overflow=='visible')s.fullscreen_overflow='auto';if(tinymce.isIE&&s.fullscreen_overflow=='scroll')s.fullscreen_overflow='auto';if(tinymce.isIE&&(s.fullscreen_html_overflow=='visible'||s.fullscreen_html_overflow=='scroll'))s.fullscreen_html_overflow='auto';if(s.fullscreen_overflow=='0px')s.fullscreen_overflow='';DOM.setStyle(DOM.doc.body,'overflow','hidden');de.style.overflow='hidden';vp=DOM.getViewPort();DOM.win.scrollTo(0,0);if(tinymce.isIE)vp.h-=1;n=DOM.add(DOM.doc.body,'div',{id:'mce_fullscreen_container',style:'position:'+(tinymce.isIE6||(tinymce.isIE&&!DOM.boxModel)?'absolute':'fixed')+';top:0;left:0;width:'+vp.w+'px;height:'+vp.h+'px;z-index:200000;'});DOM.add(n,'div',{id:'mce_fullscreen'});tinymce.each(ed.settings,function(v,n){s[n]=v;});s.id='mce_fullscreen';s.width=n.clientWidth;s.height=n.clientHeight-15;s.fullscreen_is_enabled=true;s.fullscreen_editor_id=ed.id;s.theme_advanced_resizing=false;s.save_onsavecallback=function(){ed.setContent(tinyMCE.get(s.id).getContent({format:'raw'}),{format:'raw'});ed.execCommand('mceSave');};tinymce.each(ed.getParam('fullscreen_settings'),function(v,k){s[k]=v;});if(s.theme_advanced_toolbar_location==='external')s.theme_advanced_toolbar_location='top';t.fullscreenEditor=new tinymce.Editor('mce_fullscreen',s);t.fullscreenEditor.onInit.add(function(){t.fullscreenEditor.setContent(ed.getContent());t.fullscreenEditor.focus();});t.fullscreenEditor.render();tinyMCE.add(t.fullscreenEditor);t.fullscreenElement=new tinymce.dom.Element('mce_fullscreen_container');t.fullscreenElement.update();t.resizeFunc=tinymce.dom.Event.add(DOM.win,'resize',function(){var vp=tinymce.DOM.getViewPort();t.fullscreenEditor.theme.resizeTo(vp.w,vp.h);});}});ed.addButton('fullscreen',{title:'fullscreen.desc',cmd:'mceFullScreen'});ed.onNodeChange.add(function(ed,cm){cm.setActive('fullscreen',ed.getParam('fullscreen_is_enabled'));});},getInfo:function(){return{longname:'Fullscreen',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('fullscreen',tinymce.plugins.FullScreenPlugin);})();
|
||||
(function(){var a=tinymce.DOM;tinymce.create("tinymce.plugins.FullScreenPlugin",{init:function(c,d){var e=this,f={},b;e.editor=c;c.addCommand("mceFullScreen",function(){var h,i=a.doc.documentElement;if(c.getParam("fullscreen_is_enabled")){if(c.getParam("fullscreen_new_window")){closeFullscreen()}else{a.win.setTimeout(function(){tinymce.dom.Event.remove(a.win,"resize",e.resizeFunc);tinyMCE.get(c.getParam("fullscreen_editor_id")).setContent(c.getContent({format:"raw"}),{format:"raw"});tinyMCE.remove(c);a.remove("mce_fullscreen_container");i.style.overflow=c.getParam("fullscreen_html_overflow");a.setStyle(a.doc.body,"overflow",c.getParam("fullscreen_overflow"));a.win.scrollTo(c.getParam("fullscreen_scrollx"),c.getParam("fullscreen_scrolly"));tinyMCE.settings=tinyMCE.oldSettings},10)}return}if(c.getParam("fullscreen_new_window")){h=a.win.open(d+"/fullscreen.htm","mceFullScreenPopup","fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width="+screen.availWidth+",height="+screen.availHeight);try{h.resizeTo(screen.availWidth,screen.availHeight)}catch(g){}}else{tinyMCE.oldSettings=tinyMCE.settings;f.fullscreen_overflow=a.getStyle(a.doc.body,"overflow",1)||"auto";f.fullscreen_html_overflow=a.getStyle(i,"overflow",1);b=a.getViewPort();f.fullscreen_scrollx=b.x;f.fullscreen_scrolly=b.y;if(tinymce.isOpera&&f.fullscreen_overflow=="visible"){f.fullscreen_overflow="auto"}if(tinymce.isIE&&f.fullscreen_overflow=="scroll"){f.fullscreen_overflow="auto"}if(tinymce.isIE&&(f.fullscreen_html_overflow=="visible"||f.fullscreen_html_overflow=="scroll")){f.fullscreen_html_overflow="auto"}if(f.fullscreen_overflow=="0px"){f.fullscreen_overflow=""}a.setStyle(a.doc.body,"overflow","hidden");i.style.overflow="hidden";b=a.getViewPort();a.win.scrollTo(0,0);if(tinymce.isIE){b.h-=1}n=a.add(a.doc.body,"div",{id:"mce_fullscreen_container",style:"position:"+(tinymce.isIE6||(tinymce.isIE&&!a.boxModel)?"absolute":"fixed")+";top:0;left:0;width:"+b.w+"px;height:"+b.h+"px;z-index:200000;"});a.add(n,"div",{id:"mce_fullscreen"});tinymce.each(c.settings,function(j,k){f[k]=j});f.id="mce_fullscreen";f.width=n.clientWidth;f.height=n.clientHeight-15;f.fullscreen_is_enabled=true;f.fullscreen_editor_id=c.id;f.theme_advanced_resizing=false;f.save_onsavecallback=function(){c.setContent(tinyMCE.get(f.id).getContent({format:"raw"}),{format:"raw"});c.execCommand("mceSave")};tinymce.each(c.getParam("fullscreen_settings"),function(l,j){f[j]=l});if(f.theme_advanced_toolbar_location==="external"){f.theme_advanced_toolbar_location="top"}e.fullscreenEditor=new tinymce.Editor("mce_fullscreen",f);e.fullscreenEditor.onInit.add(function(){e.fullscreenEditor.setContent(c.getContent());e.fullscreenEditor.focus()});e.fullscreenEditor.render();tinyMCE.add(e.fullscreenEditor);e.fullscreenElement=new tinymce.dom.Element("mce_fullscreen_container");e.fullscreenElement.update();e.resizeFunc=tinymce.dom.Event.add(a.win,"resize",function(){var j=tinymce.DOM.getViewPort();e.fullscreenEditor.theme.resizeTo(j.w,j.h)})}});c.addButton("fullscreen",{title:"fullscreen.desc",cmd:"mceFullScreen"});c.onNodeChange.add(function(h,g){g.setActive("fullscreen",h.getParam("fullscreen_is_enabled"))})},getInfo:function(){return{longname:"Fullscreen",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("fullscreen",tinymce.plugins.FullScreenPlugin)})();
|
||||
@@ -96,7 +96,6 @@
|
||||
// Add onunload
|
||||
tinymce.dom.Event.add(window, "beforeunload", unloadHandler);
|
||||
</script>
|
||||
<base target="_self" />
|
||||
</head>
|
||||
<body style="margin:0;overflow:hidden;width:100%;height:100%" scrolling="no" scroll="no">
|
||||
<form onsubmit="doParentSubmit();">
|
||||
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.IESpell',{init:function(ed,url){var t=this,sp;if(!tinymce.isIE)return;t.editor=ed;ed.addCommand('mceIESpell',function(){try{sp=new ActiveXObject("ieSpell.ieSpellExtension");sp.CheckDocumentNode(ed.getDoc().documentElement);}catch(e){if(e.number==-2146827859){ed.windowManager.confirm(ed.getLang("iespell.download"),function(s){if(s)window.open('http://www.iespell.com/download.php','ieSpellDownload','');});}else ed.windowManager.alert("Error Loading ieSpell: Exception "+e.number);}});ed.addButton('iespell',{title:'iespell.iespell_desc',cmd:'mceIESpell'});},getInfo:function(){return{longname:'IESpell (IE Only)',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/iespell',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('iespell',tinymce.plugins.IESpell);})();
|
||||
(function(){tinymce.create("tinymce.plugins.IESpell",{init:function(a,b){var c=this,d;if(!tinymce.isIE){return}c.editor=a;a.addCommand("mceIESpell",function(){try{d=new ActiveXObject("ieSpell.ieSpellExtension");d.CheckDocumentNode(a.getDoc().documentElement)}catch(f){if(f.number==-2146827859){a.windowManager.confirm(a.getLang("iespell.download"),function(e){if(e){window.open("http://www.iespell.com/download.php","ieSpellDownload","")}})}else{a.windowManager.alert("Error Loading ieSpell: Exception "+f.number)}}});a.addButton("iespell",{title:"iespell.iespell_desc",cmd:"mceIESpell"})},getInfo:function(){return{longname:"IESpell (IE Only)",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/iespell",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("iespell",tinymce.plugins.IESpell)})();
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: editor_plugin_src.js 961 2008-11-14 10:31:07Z spocke $
|
||||
* $Id: editor_plugin_src.js 1150 2009-06-01 11:50:46Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
// Only store selection if the type is a normal window
|
||||
if (!f.type)
|
||||
t.bookmark = ed.selection.getBookmark('simple');
|
||||
t.bookmark = ed.selection.getBookmark(1);
|
||||
|
||||
id = DOM.uniqueId();
|
||||
vp = DOM.getViewPort();
|
||||
@@ -266,7 +266,7 @@
|
||||
DOM.setStyle('mceModalBlocker', 'z-index', t.zIndex - 1);
|
||||
|
||||
if (tinymce.isIE6 || /Firefox\/2\./.test(navigator.userAgent) || (tinymce.isIE && !DOM.boxModel))
|
||||
DOM.setStyles('mceModalBlocker', {position : 'absolute', width : vp.w - 2, height : vp.h - 2});
|
||||
DOM.setStyles('mceModalBlocker', {position : 'absolute', left : vp.x, top : vp.y, width : vp.w - 2, height : vp.h - 2});
|
||||
|
||||
t.focus(id);
|
||||
t._fixIELayout(id, 1);
|
||||
@@ -358,7 +358,7 @@
|
||||
});
|
||||
|
||||
if (tinymce.isIE6 || (tinymce.isIE && !DOM.boxModel))
|
||||
DOM.setStyles('mceEventBlocker', {position : 'absolute', width : vp.w - 2, height : vp.h - 2});
|
||||
DOM.setStyles('mceEventBlocker', {position : 'absolute', left : vp.x, top : vp.y, width : vp.w - 2, height : vp.h - 2});
|
||||
|
||||
eb = new Element('mceEventBlocker');
|
||||
eb.update();
|
||||
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.InsertDateTime',{init:function(ed,url){var t=this;t.editor=ed;ed.addCommand('mceInsertDate',function(){var str=t._getDateTime(new Date(),ed.getParam("plugin_insertdate_dateFormat",ed.getLang('insertdatetime.date_fmt')));ed.execCommand('mceInsertContent',false,str);});ed.addCommand('mceInsertTime',function(){var str=t._getDateTime(new Date(),ed.getParam("plugin_insertdate_timeFormat",ed.getLang('insertdatetime.time_fmt')));ed.execCommand('mceInsertContent',false,str);});ed.addButton('insertdate',{title:'insertdatetime.insertdate_desc',cmd:'mceInsertDate'});ed.addButton('inserttime',{title:'insertdatetime.inserttime_desc',cmd:'mceInsertTime'});},getInfo:function(){return{longname:'Insert date/time',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/insertdatetime',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_getDateTime:function(d,fmt){var ed=this.editor;function addZeros(value,len){value=""+value;if(value.length<len){for(var i=0;i<(len-value.length);i++)value="0"+value;}return value;};fmt=fmt.replace("%D","%m/%d/%y");fmt=fmt.replace("%r","%I:%M:%S %p");fmt=fmt.replace("%Y",""+d.getFullYear());fmt=fmt.replace("%y",""+d.getYear());fmt=fmt.replace("%m",addZeros(d.getMonth()+1,2));fmt=fmt.replace("%d",addZeros(d.getDate(),2));fmt=fmt.replace("%H",""+addZeros(d.getHours(),2));fmt=fmt.replace("%M",""+addZeros(d.getMinutes(),2));fmt=fmt.replace("%S",""+addZeros(d.getSeconds(),2));fmt=fmt.replace("%I",""+((d.getHours()+11)%12+1));fmt=fmt.replace("%p",""+(d.getHours()<12?"AM":"PM"));fmt=fmt.replace("%B",""+ed.getLang("insertdatetime.months_long").split(',')[d.getMonth()]);fmt=fmt.replace("%b",""+ed.getLang("insertdatetime.months_short").split(',')[d.getMonth()]);fmt=fmt.replace("%A",""+ed.getLang("insertdatetime.day_long").split(',')[d.getDay()]);fmt=fmt.replace("%a",""+ed.getLang("insertdatetime.day_short").split(',')[d.getDay()]);fmt=fmt.replace("%%","%");return fmt;}});tinymce.PluginManager.add('insertdatetime',tinymce.plugins.InsertDateTime);})();
|
||||
(function(){tinymce.create("tinymce.plugins.InsertDateTime",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceInsertDate",function(){var d=c._getDateTime(new Date(),a.getParam("plugin_insertdate_dateFormat",a.getLang("insertdatetime.date_fmt")));a.execCommand("mceInsertContent",false,d)});a.addCommand("mceInsertTime",function(){var d=c._getDateTime(new Date(),a.getParam("plugin_insertdate_timeFormat",a.getLang("insertdatetime.time_fmt")));a.execCommand("mceInsertContent",false,d)});a.addButton("insertdate",{title:"insertdatetime.insertdate_desc",cmd:"mceInsertDate"});a.addButton("inserttime",{title:"insertdatetime.inserttime_desc",cmd:"mceInsertTime"})},getInfo:function(){return{longname:"Insert date/time",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/insertdatetime",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_getDateTime:function(e,a){var c=this.editor;function b(g,d){g=""+g;if(g.length<d){for(var f=0;f<(d-g.length);f++){g="0"+g}}return g}a=a.replace("%D","%m/%d/%y");a=a.replace("%r","%I:%M:%S %p");a=a.replace("%Y",""+e.getFullYear());a=a.replace("%y",""+e.getYear());a=a.replace("%m",b(e.getMonth()+1,2));a=a.replace("%d",b(e.getDate(),2));a=a.replace("%H",""+b(e.getHours(),2));a=a.replace("%M",""+b(e.getMinutes(),2));a=a.replace("%S",""+b(e.getSeconds(),2));a=a.replace("%I",""+((e.getHours()+11)%12+1));a=a.replace("%p",""+(e.getHours()<12?"AM":"PM"));a=a.replace("%B",""+c.getLang("insertdatetime.months_long").split(",")[e.getMonth()]);a=a.replace("%b",""+c.getLang("insertdatetime.months_short").split(",")[e.getMonth()]);a=a.replace("%A",""+c.getLang("insertdatetime.day_long").split(",")[e.getDay()]);a=a.replace("%a",""+c.getLang("insertdatetime.day_short").split(",")[e.getDay()]);a=a.replace("%%","%");return a}});tinymce.PluginManager.add("insertdatetime",tinymce.plugins.InsertDateTime)})();
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.Layer',{init:function(ed,url){var t=this;t.editor=ed;ed.addCommand('mceInsertLayer',t._insertLayer,t);ed.addCommand('mceMoveForward',function(){t._move(1);});ed.addCommand('mceMoveBackward',function(){t._move(-1);});ed.addCommand('mceMakeAbsolute',function(){t._toggleAbsolute();});ed.addButton('moveforward',{title:'layer.forward_desc',cmd:'mceMoveForward'});ed.addButton('movebackward',{title:'layer.backward_desc',cmd:'mceMoveBackward'});ed.addButton('absolute',{title:'layer.absolute_desc',cmd:'mceMakeAbsolute'});ed.addButton('insertlayer',{title:'layer.insertlayer_desc',cmd:'mceInsertLayer'});ed.onInit.add(function(){if(tinymce.isIE)ed.getDoc().execCommand('2D-Position',false,true);});ed.onNodeChange.add(t._nodeChange,t);ed.onVisualAid.add(t._visualAid,t);},getInfo:function(){return{longname:'Layer',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/layer',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_nodeChange:function(ed,cm,n){var le,p;le=this._getParentLayer(n);p=ed.dom.getParent(n,'DIV,P,IMG');if(!p){cm.setDisabled('absolute',1);cm.setDisabled('moveforward',1);cm.setDisabled('movebackward',1);}else{cm.setDisabled('absolute',0);cm.setDisabled('moveforward',!le);cm.setDisabled('movebackward',!le);cm.setActive('absolute',le&&le.style.position.toLowerCase()=="absolute");}},_visualAid:function(ed,e,s){var dom=ed.dom;tinymce.each(dom.select('div,p',e),function(e){if(/^(absolute|relative|static)$/i.test(e.style.position)){if(s)dom.addClass(e,'mceItemVisualAid');else dom.removeClass(e,'mceItemVisualAid');}});},_move:function(d){var ed=this.editor,i,z=[],le=this._getParentLayer(ed.selection.getNode()),ci=-1,fi=-1,nl;nl=[];tinymce.walk(ed.getBody(),function(n){if(n.nodeType==1&&/^(absolute|relative|static)$/i.test(n.style.position))nl.push(n);},'childNodes');for(i=0;i<nl.length;i++){z[i]=nl[i].style.zIndex?parseInt(nl[i].style.zIndex):0;if(ci<0&&nl[i]==le)ci=i;}if(d<0){for(i=0;i<z.length;i++){if(z[i]<z[ci]){fi=i;break;}}if(fi>-1){nl[ci].style.zIndex=z[fi];nl[fi].style.zIndex=z[ci];}else{if(z[ci]>0)nl[ci].style.zIndex=z[ci]-1;}}else{for(i=0;i<z.length;i++){if(z[i]>z[ci]){fi=i;break;}}if(fi>-1){nl[ci].style.zIndex=z[fi];nl[fi].style.zIndex=z[ci];}else nl[ci].style.zIndex=z[ci]+1;}ed.execCommand('mceRepaint');},_getParentLayer:function(n){return this.editor.dom.getParent(n,function(n){return n.nodeType==1&&/^(absolute|relative|static)$/i.test(n.style.position);});},_insertLayer:function(){var ed=this.editor,p=ed.dom.getPos(ed.dom.getParent(ed.selection.getNode(),'*'));ed.dom.add(ed.getBody(),'div',{style:{position:'absolute',left:p.x,top:(p.y>20?p.y:20),width:100,height:100},'class':'mceItemVisualAid'},ed.selection.getContent()||ed.getLang('layer.content'));},_toggleAbsolute:function(){var ed=this.editor,le=this._getParentLayer(ed.selection.getNode());if(!le)le=ed.dom.getParent(ed.selection.getNode(),'DIV,P,IMG');if(le){if(le.style.position.toLowerCase()=="absolute"){ed.dom.setStyles(le,{position:'',left:'',top:'',width:'',height:''});ed.dom.removeClass(le,'mceItemVisualAid');}else{if(le.style.left=="")le.style.left=20+'px';if(le.style.top=="")le.style.top=20+'px';if(le.style.width=="")le.style.width=le.width?(le.width+'px'):'100px';if(le.style.height=="")le.style.height=le.height?(le.height+'px'):'100px';le.style.position="absolute";ed.addVisual(ed.getBody());}ed.execCommand('mceRepaint');ed.nodeChanged();}}});tinymce.PluginManager.add('layer',tinymce.plugins.Layer);})();
|
||||
(function(){tinymce.create("tinymce.plugins.Layer",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceInsertLayer",c._insertLayer,c);a.addCommand("mceMoveForward",function(){c._move(1)});a.addCommand("mceMoveBackward",function(){c._move(-1)});a.addCommand("mceMakeAbsolute",function(){c._toggleAbsolute()});a.addButton("moveforward",{title:"layer.forward_desc",cmd:"mceMoveForward"});a.addButton("movebackward",{title:"layer.backward_desc",cmd:"mceMoveBackward"});a.addButton("absolute",{title:"layer.absolute_desc",cmd:"mceMakeAbsolute"});a.addButton("insertlayer",{title:"layer.insertlayer_desc",cmd:"mceInsertLayer"});a.onInit.add(function(){if(tinymce.isIE){a.getDoc().execCommand("2D-Position",false,true)}});a.onNodeChange.add(c._nodeChange,c);a.onVisualAid.add(c._visualAid,c)},getInfo:function(){return{longname:"Layer",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/layer",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_nodeChange:function(b,a,e){var c,d;c=this._getParentLayer(e);d=b.dom.getParent(e,"DIV,P,IMG");if(!d){a.setDisabled("absolute",1);a.setDisabled("moveforward",1);a.setDisabled("movebackward",1)}else{a.setDisabled("absolute",0);a.setDisabled("moveforward",!c);a.setDisabled("movebackward",!c);a.setActive("absolute",c&&c.style.position.toLowerCase()=="absolute")}},_visualAid:function(a,c,b){var d=a.dom;tinymce.each(d.select("div,p",c),function(f){if(/^(absolute|relative|static)$/i.test(f.style.position)){if(b){d.addClass(f,"mceItemVisualAid")}else{d.removeClass(f,"mceItemVisualAid")}}})},_move:function(h){var b=this.editor,f,g=[],e=this._getParentLayer(b.selection.getNode()),c=-1,j=-1,a;a=[];tinymce.walk(b.getBody(),function(d){if(d.nodeType==1&&/^(absolute|relative|static)$/i.test(d.style.position)){a.push(d)}},"childNodes");for(f=0;f<a.length;f++){g[f]=a[f].style.zIndex?parseInt(a[f].style.zIndex):0;if(c<0&&a[f]==e){c=f}}if(h<0){for(f=0;f<g.length;f++){if(g[f]<g[c]){j=f;break}}if(j>-1){a[c].style.zIndex=g[j];a[j].style.zIndex=g[c]}else{if(g[c]>0){a[c].style.zIndex=g[c]-1}}}else{for(f=0;f<g.length;f++){if(g[f]>g[c]){j=f;break}}if(j>-1){a[c].style.zIndex=g[j];a[j].style.zIndex=g[c]}else{a[c].style.zIndex=g[c]+1}}b.execCommand("mceRepaint")},_getParentLayer:function(a){return this.editor.dom.getParent(a,function(b){return b.nodeType==1&&/^(absolute|relative|static)$/i.test(b.style.position)})},_insertLayer:function(){var a=this.editor,b=a.dom.getPos(a.dom.getParent(a.selection.getNode(),"*"));a.dom.add(a.getBody(),"div",{style:{position:"absolute",left:b.x,top:(b.y>20?b.y:20),width:100,height:100},"class":"mceItemVisualAid"},a.selection.getContent()||a.getLang("layer.content"))},_toggleAbsolute:function(){var a=this.editor,b=this._getParentLayer(a.selection.getNode());if(!b){b=a.dom.getParent(a.selection.getNode(),"DIV,P,IMG")}if(b){if(b.style.position.toLowerCase()=="absolute"){a.dom.setStyles(b,{position:"",left:"",top:"",width:"",height:""});a.dom.removeClass(b,"mceItemVisualAid")}else{if(b.style.left==""){b.style.left=20+"px"}if(b.style.top==""){b.style.top=20+"px"}if(b.style.width==""){b.style.width=b.width?(b.width+"px"):"100px"}if(b.style.height==""){b.style.height=b.height?(b.height+"px"):"100px"}b.style.position="absolute";a.addVisual(a.getBody())}a.execCommand("mceRepaint");a.nodeChanged()}}});tinymce.PluginManager.add("layer",tinymce.plugins.Layer)})();
|
||||
@@ -0,0 +1 @@
|
||||
(function(a){a.onAddEditor.addToTop(function(c,b){b.settings.inline_styles=false});a.create("tinymce.plugins.LegacyOutput",{init:function(b){b.onInit.add(function(){var c="p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",e=a.explode(b.settings.font_size_style_values),d=b.serializer;b.formatter.register({alignleft:{selector:c,attributes:{align:"left"}},aligncenter:{selector:c,attributes:{align:"center"}},alignright:{selector:c,attributes:{align:"right"}},alignfull:{selector:c,attributes:{align:"full"}},bold:{inline:"b"},italic:{inline:"i"},underline:{inline:"u"},strikethrough:{inline:"strike"},fontname:{inline:"font",attributes:{face:"%value"}},fontsize:{inline:"font",attributes:{size:function(f){return a.inArray(e,f.value)+1}}},forecolor:{inline:"font",styles:{color:"%value"}},hilitecolor:{inline:"font",styles:{backgroundColor:"%value"}}});d._setup();a.each("b,i,u,strike".split(","),function(f){var g=d.rules[f];if(!g){d.addRules(f)}});if(!d.rules.font){d.addRules("font[face|size|color|style]")}a.each(c.split(","),function(f){var h=d.rules[f],g;if(h){a.each(h.attribs,function(j,i){if(i.name=="align"){g=true;return false}});if(!g){h.attribs.push({name:"align"})}}});b.onNodeChange.add(function(g,k){var j,f,h,i;f=g.dom.getParent(g.selection.getNode(),"font");if(f){h=f.face;i=f.size}if(j=k.get("fontselect")){j.select(function(l){return l==h})}if(j=k.get("fontsizeselect")){j.select(function(m){var l=a.inArray(e,m.fontSize);return l+1==i})}})})},getInfo:function(){return{longname:"LegacyOutput",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/legacyoutput",version:a.majorVersion+"."+a.minorVersion}}});a.PluginManager.add("legacyoutput",a.plugins.LegacyOutput)})(tinymce);
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* editor_plugin_src.js
|
||||
*
|
||||
* Copyright 2009, Moxiecode Systems AB
|
||||
* Released under LGPL License.
|
||||
*
|
||||
* License: http://tinymce.moxiecode.com/license
|
||||
* Contributing: http://tinymce.moxiecode.com/contributing
|
||||
*
|
||||
* This plugin will force TinyMCE to produce deprecated legacy output such as font elements, u elements, align
|
||||
* attributes and so forth. There are a few cases where these old items might be needed for example in email applications or with Flash
|
||||
*
|
||||
* However you should NOT use this plugin if you are building some system that produces web contents such as a CMS. All these elements are
|
||||
* not apart of the newer specifications for HTML and XHTML.
|
||||
*/
|
||||
|
||||
(function(tinymce) {
|
||||
// Override inline_styles setting to force TinyMCE to produce deprecated contents
|
||||
tinymce.onAddEditor.addToTop(function(tinymce, editor) {
|
||||
editor.settings.inline_styles = false;
|
||||
});
|
||||
|
||||
// Create the legacy ouput plugin
|
||||
tinymce.create('tinymce.plugins.LegacyOutput', {
|
||||
init : function(editor) {
|
||||
editor.onInit.add(function() {
|
||||
var alignElements = 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img',
|
||||
fontSizes = tinymce.explode(editor.settings.font_size_style_values),
|
||||
serializer = editor.serializer;
|
||||
|
||||
// Override some internal formats to produce legacy elements and attributes
|
||||
editor.formatter.register({
|
||||
// Change alignment formats to use the deprecated align attribute
|
||||
alignleft : {selector : alignElements, attributes : {align : 'left'}},
|
||||
aligncenter : {selector : alignElements, attributes : {align : 'center'}},
|
||||
alignright : {selector : alignElements, attributes : {align : 'right'}},
|
||||
alignfull : {selector : alignElements, attributes : {align : 'full'}},
|
||||
|
||||
// Change the basic formatting elements to use deprecated element types
|
||||
bold : {inline : 'b'},
|
||||
italic : {inline : 'i'},
|
||||
underline : {inline : 'u'},
|
||||
strikethrough : {inline : 'strike'},
|
||||
|
||||
// Change font size and font family to use the deprecated font element
|
||||
fontname : {inline : 'font', attributes : {face : '%value'}},
|
||||
fontsize : {
|
||||
inline : 'font',
|
||||
attributes : {
|
||||
size : function(vars) {
|
||||
return tinymce.inArray(fontSizes, vars.value) + 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Setup font elements for colors as well
|
||||
forecolor : {inline : 'font', styles : {color : '%value'}},
|
||||
hilitecolor : {inline : 'font', styles : {backgroundColor : '%value'}}
|
||||
});
|
||||
|
||||
// Force parsing of the serializer rules
|
||||
serializer._setup();
|
||||
|
||||
// Check that deprecated elements are allowed if not add them
|
||||
tinymce.each('b,i,u,strike'.split(','), function(name) {
|
||||
var rule = serializer.rules[name];
|
||||
|
||||
if (!rule)
|
||||
serializer.addRules(name);
|
||||
});
|
||||
|
||||
// Add font element if it's missing
|
||||
if (!serializer.rules["font"])
|
||||
serializer.addRules("font[face|size|color|style]");
|
||||
|
||||
// Add the missing and depreacted align attribute for the serialization engine
|
||||
tinymce.each(alignElements.split(','), function(name) {
|
||||
var rule = serializer.rules[name], found;
|
||||
|
||||
if (rule) {
|
||||
tinymce.each(rule.attribs, function(name, attr) {
|
||||
if (attr.name == 'align') {
|
||||
found = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (!found)
|
||||
rule.attribs.push({name : 'align'});
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for the onNodeChange event so that we can do special logic for the font size and font name drop boxes
|
||||
editor.onNodeChange.add(function(editor, control_manager) {
|
||||
var control, fontElm, fontName, fontSize;
|
||||
|
||||
// Find font element get it's name and size
|
||||
fontElm = editor.dom.getParent(editor.selection.getNode(), 'font');
|
||||
if (fontElm) {
|
||||
fontName = fontElm.face;
|
||||
fontSize = fontElm.size;
|
||||
}
|
||||
|
||||
// Select/unselect the font name in droplist
|
||||
if (control = control_manager.get('fontselect')) {
|
||||
control.select(function(value) {
|
||||
return value == fontName;
|
||||
});
|
||||
}
|
||||
|
||||
// Select/unselect the font size in droplist
|
||||
if (control = control_manager.get('fontsizeselect')) {
|
||||
control.select(function(value) {
|
||||
var index = tinymce.inArray(fontSizes, value.fontSize);
|
||||
|
||||
return index + 1 == fontSize;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getInfo : function() {
|
||||
return {
|
||||
longname : 'LegacyOutput',
|
||||
author : 'Moxiecode Systems AB',
|
||||
authorurl : 'http://tinymce.moxiecode.com',
|
||||
infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/legacyoutput',
|
||||
version : tinymce.majorVersion + "." + tinymce.minorVersion
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Register plugin
|
||||
tinymce.PluginManager.add('legacyoutput', tinymce.plugins.LegacyOutput);
|
||||
})(tinymce);
|
||||
File diff suppressed because one or more lines are too long
+25
-14
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: editor_plugin_src.js 952 2008-11-03 17:56:04Z spocke $
|
||||
* $Id: editor_plugin_src.js 1222 2009-09-03 17:26:47Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
@@ -61,7 +61,7 @@
|
||||
if (ed.settings.content_css !== false)
|
||||
ed.dom.loadCSS(url + "/css/content.css");
|
||||
|
||||
if (ed.theme.onResolveName) {
|
||||
if (ed.theme && ed.theme.onResolveName) {
|
||||
ed.theme.onResolveName.add(function(th, o) {
|
||||
if (o.name == 'img') {
|
||||
each(lo, function(v, k) {
|
||||
@@ -165,14 +165,14 @@
|
||||
o.content = o.content.replace(/_mce_value=/g, 'value=');
|
||||
});
|
||||
|
||||
if (ed.getParam('media_use_script')) {
|
||||
function getAttr(s, n) {
|
||||
n = new RegExp(n + '=\"([^\"]+)\"', 'g').exec(s);
|
||||
function getAttr(s, n) {
|
||||
n = new RegExp(n + '=\"([^\"]+)\"', 'g').exec(s);
|
||||
|
||||
return n ? ed.dom.decode(n[1]) : '';
|
||||
};
|
||||
return n ? ed.dom.decode(n[1]) : '';
|
||||
};
|
||||
|
||||
ed.onPostProcess.add(function(ed, o) {
|
||||
ed.onPostProcess.add(function(ed, o) {
|
||||
if (ed.getParam('media_use_script')) {
|
||||
o.content = o.content.replace(/<img[^>]+>/g, function(im) {
|
||||
var cl = getAttr(im, 'class');
|
||||
|
||||
@@ -185,8 +185,8 @@
|
||||
|
||||
return im;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getInfo : function() {
|
||||
@@ -233,16 +233,20 @@
|
||||
|
||||
if (stc) {
|
||||
ob = dom.create('span', {
|
||||
id : p.id,
|
||||
mce_name : 'object',
|
||||
type : 'application/x-shockwave-flash',
|
||||
data : p.src,
|
||||
style : dom.getAttrib(n, 'style'),
|
||||
width : o.width,
|
||||
height : o.height
|
||||
});
|
||||
} else {
|
||||
ob = dom.create('span', {
|
||||
id : p.id,
|
||||
mce_name : 'object',
|
||||
classid : "clsid:" + o.classid,
|
||||
style : dom.getAttrib(n, 'style'),
|
||||
codebase : o.codebase,
|
||||
width : o.width,
|
||||
height : o.height
|
||||
@@ -250,9 +254,9 @@
|
||||
}
|
||||
|
||||
each (p, function(v, k) {
|
||||
if (!/^(width|height|codebase|classid|_cx|_cy)$/.test(k)) {
|
||||
if (!/^(width|height|codebase|classid|id|_cx|_cy)$/.test(k)) {
|
||||
// Use url instead of src in IE for Windows media
|
||||
if (o.type == 'application/x-mplayer2' && k == 'src')
|
||||
if (o.type == 'application/x-mplayer2' && k == 'src' && !p.url)
|
||||
k = 'url';
|
||||
|
||||
if (v)
|
||||
@@ -261,7 +265,7 @@
|
||||
});
|
||||
|
||||
if (!stc)
|
||||
dom.add(ob, 'span', tinymce.extend({mce_name : 'embed', type : o.type}, p));
|
||||
dom.add(ob, 'span', tinymce.extend({mce_name : 'embed', type : o.type, style : dom.getAttrib(n, 'style')}, p));
|
||||
|
||||
return ob;
|
||||
},
|
||||
@@ -337,13 +341,14 @@
|
||||
_createImg : function(cl, n) {
|
||||
var im, dom = this.editor.dom, pa = {}, ti = '', args;
|
||||
|
||||
args = ['id', 'name', 'width', 'height', 'bgcolor', 'align', 'flashvars', 'src', 'wmode', 'allowfullscreen', 'quality'];
|
||||
args = ['id', 'name', 'width', 'height', 'bgcolor', 'align', 'flashvars', 'src', 'wmode', 'allowfullscreen', 'quality', 'data'];
|
||||
|
||||
// Create image
|
||||
im = dom.create('img', {
|
||||
src : this.url + '/img/trans.gif',
|
||||
width : dom.getAttrib(n, 'width') || 100,
|
||||
height : dom.getAttrib(n, 'height') || 100,
|
||||
style : dom.getAttrib(n, 'style'),
|
||||
'class' : cl
|
||||
});
|
||||
|
||||
@@ -367,6 +372,12 @@
|
||||
delete pa.movie;
|
||||
}
|
||||
|
||||
// No src try data
|
||||
if (!pa.src) {
|
||||
pa.src = pa.data;
|
||||
delete pa.data;
|
||||
}
|
||||
|
||||
// Merge with embed args
|
||||
n = dom.select('.mceItemEmbed', n)[0];
|
||||
if (n) {
|
||||
|
||||
+3
-3
@@ -218,7 +218,7 @@ function insertMedia() {
|
||||
break;
|
||||
}
|
||||
|
||||
if (fe.width != f.width.value || fe.height != f.height.height)
|
||||
if (fe.width != f.width.value || fe.height != f.height.value)
|
||||
ed.execCommand('mceRepaint');
|
||||
|
||||
fe.title = serializeParameters();
|
||||
@@ -469,7 +469,7 @@ function setBool(pl, p, n) {
|
||||
if (typeof(pl[n]) == "undefined")
|
||||
return;
|
||||
|
||||
document.forms[0].elements[p + "_" + n].checked = pl[n];
|
||||
document.forms[0].elements[p + "_" + n].checked = pl[n] != 'false';
|
||||
}
|
||||
|
||||
function setStr(pl, p, n) {
|
||||
@@ -490,7 +490,7 @@ function getBool(p, n, d, tv, fv) {
|
||||
tv = typeof(tv) == 'undefined' ? 'true' : "'" + jsEncode(tv) + "'";
|
||||
fv = typeof(fv) == 'undefined' ? 'false' : "'" + jsEncode(fv) + "'";
|
||||
|
||||
return (v == d) ? '' : n + (v ? ':' + tv + ',' : ':' + fv + ',');
|
||||
return (v == d) ? '' : n + (v ? ':' + tv + ',' : ":\'" + fv + "\',");
|
||||
}
|
||||
|
||||
function getStr(p, n, d) {
|
||||
|
||||
+2
-4
@@ -9,7 +9,6 @@
|
||||
<script type="text/javascript" src="../../utils/form_utils.js"></script>
|
||||
<script type="text/javascript" src="../../utils/editable_selects.js"></script>
|
||||
<link href="css/media.css" rel="stylesheet" type="text/css" />
|
||||
<base target="_self" />
|
||||
</head>
|
||||
<body style="display: none">
|
||||
<form onsubmit="insertMedia();return false;" action="#">
|
||||
@@ -52,7 +51,7 @@
|
||||
</tr>
|
||||
<tr id="linklistrow">
|
||||
<td><label for="linklist">{#media_dlg.list}</label></td>
|
||||
<td id="linklistcontainer"> </td>
|
||||
<td id="linklistcontainer"><select id="linklist"><option value=""></option></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="width">{#media_dlg.size}</label></td>
|
||||
@@ -260,8 +259,7 @@
|
||||
<td><label for="flv_defaultvolume">{#media_dlg.flv_defaultvolume}</label></td>
|
||||
<td><input type="text" id="flv_defaultvolume" name="flv_defaultvolume" onchange="generatePreview();" /></td>
|
||||
|
||||
<td><label for="flv_starttime">{#media_dlg.flv_starttime}</label></td>
|
||||
<td><input type="text" id="flv_starttime" name="flv_starttime" onchange="generatePreview();" /></td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.Nonbreaking',{init:function(ed,url){var t=this;t.editor=ed;ed.addCommand('mceNonBreaking',function(){ed.execCommand('mceInsertContent',false,(ed.plugins.visualchars&&ed.plugins.visualchars.state)?'<span class="mceItemHidden mceVisualNbsp">·</span>':' ');});ed.addButton('nonbreaking',{title:'nonbreaking.nonbreaking_desc',cmd:'mceNonBreaking'});if(ed.getParam('nonbreaking_force_tab')){ed.onKeyDown.add(function(ed,e){if(tinymce.isIE&&e.keyCode==9){ed.execCommand('mceNonBreaking');ed.execCommand('mceNonBreaking');ed.execCommand('mceNonBreaking');tinymce.dom.Event.cancel(e);}});}},getInfo:function(){return{longname:'Nonbreaking space',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/nonbreaking',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('nonbreaking',tinymce.plugins.Nonbreaking);})();
|
||||
(function(){tinymce.create("tinymce.plugins.Nonbreaking",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceNonBreaking",function(){a.execCommand("mceInsertContent",false,(a.plugins.visualchars&&a.plugins.visualchars.state)?'<span class="mceItemHidden mceVisualNbsp">·</span>':" ")});a.addButton("nonbreaking",{title:"nonbreaking.nonbreaking_desc",cmd:"mceNonBreaking"});if(a.getParam("nonbreaking_force_tab")){a.onKeyDown.add(function(d,f){if(tinymce.isIE&&f.keyCode==9){d.execCommand("mceNonBreaking");d.execCommand("mceNonBreaking");d.execCommand("mceNonBreaking");tinymce.dom.Event.cancel(f)}})}},getInfo:function(){return{longname:"Nonbreaking space",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/nonbreaking",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("nonbreaking",tinymce.plugins.Nonbreaking)})();
|
||||
@@ -1 +1 @@
|
||||
(function(){var Event=tinymce.dom.Event;tinymce.create('tinymce.plugins.NonEditablePlugin',{init:function(ed,url){var t=this,editClass,nonEditClass;t.editor=ed;editClass=ed.getParam("noneditable_editable_class","mceEditable");nonEditClass=ed.getParam("noneditable_noneditable_class","mceNonEditable");ed.onNodeChange.addToTop(function(ed,cm,n){var sc,ec;sc=ed.dom.getParent(ed.selection.getStart(),function(n){return ed.dom.hasClass(n,nonEditClass);});ec=ed.dom.getParent(ed.selection.getEnd(),function(n){return ed.dom.hasClass(n,nonEditClass);});if(sc||ec){t._setDisabled(1);return false;}else t._setDisabled(0);});},getInfo:function(){return{longname:'Non editable elements',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_block:function(ed,e){var k=e.keyCode;if((k>32&&k<41)||(k>111&&k<124))return;return Event.cancel(e);},_setDisabled:function(s){var t=this,ed=t.editor;tinymce.each(ed.controlManager.controls,function(c){c.setDisabled(s);});if(s!==t.disabled){if(s){ed.onKeyDown.addToTop(t._block);ed.onKeyPress.addToTop(t._block);ed.onKeyUp.addToTop(t._block);ed.onPaste.addToTop(t._block);}else{ed.onKeyDown.remove(t._block);ed.onKeyPress.remove(t._block);ed.onKeyUp.remove(t._block);ed.onPaste.remove(t._block);}t.disabled=s;}}});tinymce.PluginManager.add('noneditable',tinymce.plugins.NonEditablePlugin);})();
|
||||
(function(){var a=tinymce.dom.Event;tinymce.create("tinymce.plugins.NonEditablePlugin",{init:function(d,e){var f=this,c,b;f.editor=d;c=d.getParam("noneditable_editable_class","mceEditable");b=d.getParam("noneditable_noneditable_class","mceNonEditable");d.onNodeChange.addToTop(function(h,g,k){var j,i;j=h.dom.getParent(h.selection.getStart(),function(l){return h.dom.hasClass(l,b)});i=h.dom.getParent(h.selection.getEnd(),function(l){return h.dom.hasClass(l,b)});if(j||i){f._setDisabled(1);return false}else{f._setDisabled(0)}})},getInfo:function(){return{longname:"Non editable elements",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_block:function(c,d){var b=d.keyCode;if((b>32&&b<41)||(b>111&&b<124)){return}return a.cancel(d)},_setDisabled:function(d){var c=this,b=c.editor;tinymce.each(b.controlManager.controls,function(e){e.setDisabled(d)});if(d!==c.disabled){if(d){b.onKeyDown.addToTop(c._block);b.onKeyPress.addToTop(c._block);b.onKeyUp.addToTop(c._block);b.onPaste.addToTop(c._block)}else{b.onKeyDown.remove(c._block);b.onKeyPress.remove(c._block);b.onKeyUp.remove(c._block);b.onPaste.remove(c._block)}c.disabled=d}}});tinymce.PluginManager.add("noneditable",tinymce.plugins.NonEditablePlugin)})();
|
||||
@@ -1 +1 @@
|
||||
(function(){tinymce.create('tinymce.plugins.PageBreakPlugin',{init:function(ed,url){var pb='<img src="'+url+'/img/trans.gif" class="mcePageBreak mceItemNoResize" />',cls='mcePageBreak',sep=ed.getParam('pagebreak_separator','<!-- pagebreak -->'),pbRE;pbRE=new RegExp(sep.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(a){return'\\'+a;}),'g');ed.addCommand('mcePageBreak',function(){ed.execCommand('mceInsertContent',0,pb);});ed.addButton('pagebreak',{title:'pagebreak.desc',cmd:cls});ed.onInit.add(function(){if(ed.settings.content_css!==false)ed.dom.loadCSS(url+"/css/content.css");if(ed.theme.onResolveName){ed.theme.onResolveName.add(function(th,o){if(o.node.nodeName=='IMG'&&ed.dom.hasClass(o.node,cls))o.name='pagebreak';});}});ed.onClick.add(function(ed,e){e=e.target;if(e.nodeName==='IMG'&&ed.dom.hasClass(e,cls))ed.selection.select(e);});ed.onNodeChange.add(function(ed,cm,n){cm.setActive('pagebreak',n.nodeName==='IMG'&&ed.dom.hasClass(n,cls));});ed.onBeforeSetContent.add(function(ed,o){o.content=o.content.replace(pbRE,pb);});ed.onPostProcess.add(function(ed,o){if(o.get)o.content=o.content.replace(/<img[^>]+>/g,function(im){if(im.indexOf('class="mcePageBreak')!==-1)im=sep;return im;});});},getInfo:function(){return{longname:'PageBreak',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/pagebreak',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('pagebreak',tinymce.plugins.PageBreakPlugin);})();
|
||||
(function(){tinymce.create("tinymce.plugins.PageBreakPlugin",{init:function(b,d){var f='<img src="'+d+'/img/trans.gif" class="mcePageBreak mceItemNoResize" />',a="mcePageBreak",c=b.getParam("pagebreak_separator","<!-- pagebreak -->"),e;e=new RegExp(c.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(g){return"\\"+g}),"g");b.addCommand("mcePageBreak",function(){b.execCommand("mceInsertContent",0,f)});b.addButton("pagebreak",{title:"pagebreak.desc",cmd:a});b.onInit.add(function(){if(b.settings.content_css!==false){b.dom.loadCSS(d+"/css/content.css")}if(b.theme.onResolveName){b.theme.onResolveName.add(function(g,h){if(h.node.nodeName=="IMG"&&b.dom.hasClass(h.node,a)){h.name="pagebreak"}})}});b.onClick.add(function(g,h){h=h.target;if(h.nodeName==="IMG"&&g.dom.hasClass(h,a)){g.selection.select(h)}});b.onNodeChange.add(function(h,g,i){g.setActive("pagebreak",i.nodeName==="IMG"&&h.dom.hasClass(i,a))});b.onBeforeSetContent.add(function(g,h){h.content=h.content.replace(e,f)});b.onPostProcess.add(function(g,h){if(h.get){h.content=h.content.replace(/<img[^>]+>/g,function(i){if(i.indexOf('class="mcePageBreak')!==-1){i=c}return i})}})},getInfo:function(){return{longname:"PageBreak",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/pagebreak",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("pagebreak",tinymce.plugins.PageBreakPlugin)})();
|
||||
File diff suppressed because one or more lines are too long
+467
-330
@@ -1,81 +1,179 @@
|
||||
/**
|
||||
* $Id: editor_plugin_src.js 919 2008-09-08 20:31:23Z spocke $
|
||||
* $Id: editor_plugin_src.js 1225 2009-09-07 19:06:19Z spocke $
|
||||
*
|
||||
* @author Moxiecode
|
||||
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var Event = tinymce.dom.Event;
|
||||
var each = tinymce.each;
|
||||
|
||||
tinymce.create('tinymce.plugins.PastePlugin', {
|
||||
init : function(ed, url) {
|
||||
var t = this;
|
||||
var t = this, cb;
|
||||
|
||||
t.editor = ed;
|
||||
t.editor = ed;
|
||||
t.url = url;
|
||||
|
||||
// Register commands
|
||||
ed.addCommand('mcePasteText', function(ui, v) {
|
||||
if (ui) {
|
||||
if ((ed.getParam('paste_use_dialog', true)) || (!tinymce.isIE)) {
|
||||
ed.windowManager.open({
|
||||
file : url + '/pastetext.htm',
|
||||
width : 450,
|
||||
height : 400,
|
||||
inline : 1
|
||||
}, {
|
||||
plugin_url : url
|
||||
});
|
||||
} else
|
||||
t._insertText(clipboardData.getData("Text"), true);
|
||||
} else
|
||||
t._insertText(v.html, v.linebreaks);
|
||||
// Setup plugin events
|
||||
t.onPreProcess = new tinymce.util.Dispatcher(t);
|
||||
t.onPostProcess = new tinymce.util.Dispatcher(t);
|
||||
|
||||
// Register default handlers
|
||||
t.onPreProcess.add(t._preProcess);
|
||||
t.onPostProcess.add(t._postProcess);
|
||||
|
||||
// Register optional preprocess handler
|
||||
t.onPreProcess.add(function(pl, o) {
|
||||
ed.execCallback('paste_preprocess', pl, o);
|
||||
});
|
||||
|
||||
ed.addCommand('mcePasteWord', function(ui, v) {
|
||||
if (ui) {
|
||||
if ((ed.getParam('paste_use_dialog', true)) || (!tinymce.isIE)) {
|
||||
ed.windowManager.open({
|
||||
file : url + '/pasteword.htm',
|
||||
width : 450,
|
||||
height : 400,
|
||||
inline : 1
|
||||
}, {
|
||||
plugin_url : url
|
||||
});
|
||||
} else
|
||||
t._insertText(t._clipboardHTML());
|
||||
} else
|
||||
t._insertWordContent(v);
|
||||
// Register optional postprocess
|
||||
t.onPostProcess.add(function(pl, o) {
|
||||
ed.execCallback('paste_postprocess', pl, o);
|
||||
});
|
||||
|
||||
ed.addCommand('mceSelectAll', function() {
|
||||
ed.execCommand('selectall');
|
||||
// This function executes the process handlers and inserts the contents
|
||||
function process(o) {
|
||||
var dom = ed.dom;
|
||||
|
||||
// Execute pre process handlers
|
||||
t.onPreProcess.dispatch(t, o);
|
||||
|
||||
// Create DOM structure
|
||||
o.node = dom.create('div', 0, o.content);
|
||||
|
||||
// Execute post process handlers
|
||||
t.onPostProcess.dispatch(t, o);
|
||||
|
||||
// Serialize content
|
||||
o.content = ed.serializer.serialize(o.node, {getInner : 1});
|
||||
|
||||
// Insert cleaned content. We need to handle insertion of contents containing block elements separately
|
||||
if (/<(p|h[1-6]|ul|ol)/.test(o.content))
|
||||
t._insertBlockContent(ed, dom, o.content);
|
||||
else
|
||||
t._insert(o.content);
|
||||
};
|
||||
|
||||
// Add command for external usage
|
||||
ed.addCommand('mceInsertClipboardContent', function(u, o) {
|
||||
process(o);
|
||||
});
|
||||
|
||||
// Register buttons
|
||||
ed.addButton('pastetext', {title : 'paste.paste_text_desc', cmd : 'mcePasteText', ui : true});
|
||||
ed.addButton('pasteword', {title : 'paste.paste_word_desc', cmd : 'mcePasteWord', ui : true});
|
||||
ed.addButton('selectall', {title : 'paste.selectall_desc', cmd : 'mceSelectAll'});
|
||||
// This function grabs the contents from the clipboard by adding a
|
||||
// hidden div and placing the caret inside it and after the browser paste
|
||||
// is done it grabs that contents and processes that
|
||||
function grabContent(e) {
|
||||
var n, or, rng, sel = ed.selection, dom = ed.dom, body = ed.getBody(), posY;
|
||||
|
||||
if (ed.getParam("paste_auto_cleanup_on_paste", false)) {
|
||||
ed.onPaste.add(function(ed, e) {
|
||||
return t._handlePasteEvent(e)
|
||||
if (dom.get('_mcePaste'))
|
||||
return;
|
||||
|
||||
// Create container to paste into
|
||||
n = dom.add(body, 'div', {id : '_mcePaste'}, '\uFEFF');
|
||||
|
||||
// If contentEditable mode we need to find out the position of the closest element
|
||||
if (body != ed.getDoc().body)
|
||||
posY = dom.getPos(ed.selection.getStart(), body).y;
|
||||
else
|
||||
posY = body.scrollTop;
|
||||
|
||||
// Styles needs to be applied after the element is added to the document since WebKit will otherwise remove all styles
|
||||
dom.setStyles(n, {
|
||||
position : 'absolute',
|
||||
left : -10000,
|
||||
top : posY,
|
||||
width : 1,
|
||||
height : 1,
|
||||
overflow : 'hidden'
|
||||
});
|
||||
}
|
||||
|
||||
if (!tinymce.isIE && ed.getParam("paste_auto_cleanup_on_paste", false)) {
|
||||
// Force paste dialog if non IE browser
|
||||
ed.onKeyDown.add(function(ed, e) {
|
||||
if (e.ctrlKey && e.keyCode == 86) {
|
||||
window.setTimeout(function() {
|
||||
ed.execCommand("mcePasteText", true);
|
||||
}, 1);
|
||||
if (tinymce.isIE) {
|
||||
// Select the container
|
||||
rng = dom.doc.body.createTextRange();
|
||||
rng.moveToElementText(n);
|
||||
rng.execCommand('Paste');
|
||||
|
||||
Event.cancel(e);
|
||||
// Remove container
|
||||
dom.remove(n);
|
||||
|
||||
// Check if the contents was changed, if it wasn't then clipboard extraction failed probably due
|
||||
// to IE security settings so we pass the junk though better than nothing right
|
||||
if (n.innerHTML === '\uFEFF') {
|
||||
ed.execCommand('mcePasteWord');
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
// Process contents
|
||||
process({content : n.innerHTML});
|
||||
|
||||
// Block the real paste event
|
||||
return tinymce.dom.Event.cancel(e);
|
||||
} else {
|
||||
or = ed.selection.getRng();
|
||||
|
||||
// Move caret into hidden div
|
||||
n = n.firstChild;
|
||||
rng = ed.getDoc().createRange();
|
||||
rng.setStart(n, 0);
|
||||
rng.setEnd(n, 1);
|
||||
sel.setRng(rng);
|
||||
|
||||
// Wait a while and grab the pasted contents
|
||||
window.setTimeout(function() {
|
||||
var h = '', nl = dom.select('div[id=_mcePaste]');
|
||||
|
||||
// WebKit will split the div into multiple ones so this will loop through then all and join them to get the whole HTML string
|
||||
each(nl, function(n) {
|
||||
h += (dom.select('> span.Apple-style-span div', n)[0] || dom.select('> span.Apple-style-span', n)[0] || n).innerHTML;
|
||||
});
|
||||
|
||||
// Remove the nodes
|
||||
each(nl, function(n) {
|
||||
dom.remove(n);
|
||||
});
|
||||
|
||||
// Restore the old selection
|
||||
if (or)
|
||||
sel.setRng(or);
|
||||
|
||||
process({content : h});
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
|
||||
// Check if we should use the new auto process method
|
||||
if (ed.getParam('paste_auto_cleanup_on_paste', true)) {
|
||||
// Is it's Opera or older FF use key handler
|
||||
if (tinymce.isOpera || /Firefox\/2/.test(navigator.userAgent)) {
|
||||
ed.onKeyDown.add(function(ed, e) {
|
||||
if (((tinymce.isMac ? e.metaKey : e.ctrlKey) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45))
|
||||
grabContent(e);
|
||||
});
|
||||
} else {
|
||||
// Grab contents on paste event on Gecko and WebKit
|
||||
ed.onPaste.addToTop(function(ed, e) {
|
||||
return grabContent(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Block all drag/drop events
|
||||
if (ed.getParam('paste_block_drop')) {
|
||||
ed.onInit.add(function() {
|
||||
ed.dom.bind(ed.getBody(), ['dragend', 'dragover', 'draggesture', 'dragdrop', 'drop', 'drag'], function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Add legacy support
|
||||
t._legacySupport();
|
||||
},
|
||||
|
||||
getInfo : function() {
|
||||
@@ -88,304 +186,343 @@
|
||||
};
|
||||
},
|
||||
|
||||
// Private methods
|
||||
_preProcess : function(pl, o) {
|
||||
var ed = this.editor, h = o.content, process, stripClass;
|
||||
|
||||
_handlePasteEvent : function(e) {
|
||||
var html = this._clipboardHTML(), ed = this.editor, sel = ed.selection, r;
|
||||
//console.log('Before preprocess:' + o.content);
|
||||
|
||||
// Removes italic, strong etc, the if was needed due to bug #1437114
|
||||
if (ed && (r = sel.getRng()) && r.text.length > 0)
|
||||
ed.execCommand('delete');
|
||||
function process(items) {
|
||||
each(items, function(v) {
|
||||
// Remove or replace
|
||||
if (v.constructor == RegExp)
|
||||
h = h.replace(v, '');
|
||||
else
|
||||
h = h.replace(v[0], v[1]);
|
||||
});
|
||||
};
|
||||
|
||||
if (html && html.length > 0)
|
||||
ed.execCommand('mcePasteWord', false, html);
|
||||
// Detect Word content and process it more aggressive
|
||||
if (/(class=\"?Mso|style=\"[^\"]*\bmso\-|w:WordDocument)/.test(h) || o.wordContent) {
|
||||
o.wordContent = true; // Mark the pasted contents as word specific content
|
||||
//console.log('Word contents detected.');
|
||||
|
||||
return Event.cancel(e);
|
||||
// Process away some basic content
|
||||
process([
|
||||
/^\s*( )+/g, // nbsp entities at the start of contents
|
||||
/( |<br[^>]*>)+\s*$/g // nbsp entities at the end of contents
|
||||
]);
|
||||
|
||||
if (ed.getParam('paste_convert_middot_lists', true)) {
|
||||
process([
|
||||
[/<!--\[if !supportLists\]-->/gi, '$&__MCE_ITEM__'], // Convert supportLists to a list item marker
|
||||
[/(<span[^>]+:\s*symbol[^>]+>)/gi, '$1__MCE_ITEM__'], // Convert symbol spans to list items
|
||||
[/(<span[^>]+mso-list:[^>]+>)/gi, '$1__MCE_ITEM__'] // Convert mso-list to item marker
|
||||
]);
|
||||
}
|
||||
|
||||
process([
|
||||
/<!--[\s\S]+?-->/gi, // Word comments
|
||||
/<\/?(img|font|meta|link|style|div|v:\w+)[^>]*>/gi, // Remove some tags including VML content
|
||||
/<\\?\?xml[^>]*>/gi, // XML namespace declarations
|
||||
/<\/?o:[^>]*>/gi, // MS namespaced elements <o:tag>
|
||||
/ (id|name|language|type|on\w+|v:\w+)=\"([^\"]*)\"/gi, // on.., class, style and language attributes with quotes
|
||||
/ (id|name|language|type|on\w+|v:\w+)=(\w+)/gi, // on.., class, style and language attributes without quotes (IE)
|
||||
[/<(\/?)s>/gi, '<$1strike>'], // Convert <s> into <strike> for line-though
|
||||
/<script[^>]+>[\s\S]*?<\/script>/gi, // All scripts elements for msoShowComment for example
|
||||
[/ /g, '\u00a0'] // Replace nsbp entites to char since it's easier to handle
|
||||
]);
|
||||
|
||||
// Remove all spans if no styles is to be retained
|
||||
if (!ed.getParam('paste_retain_style_properties')) {
|
||||
process([
|
||||
/<\/?(span)[^>]*>/gi
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Allow for class names to be retained if desired; either all, or just the ones from Word
|
||||
// Note that the paste_strip_class_attributes: 'none, verify_css_classes: true is also a good variation.
|
||||
stripClass = ed.getParam('paste_strip_class_attributes');
|
||||
if (stripClass != 'none') {
|
||||
// Cleans everything but mceItem... classes
|
||||
function cleanClasses(str, cls) {
|
||||
var i, out = '';
|
||||
|
||||
// Remove all classes
|
||||
if (stripClass == 'all')
|
||||
return '';
|
||||
|
||||
cls = tinymce.explode(cls, ' ');
|
||||
|
||||
for (i = cls.length - 1; i >= 0; i--) {
|
||||
// Remove Mso classes
|
||||
if (!/^(Mso)/i.test(cls[i]))
|
||||
out += (!out ? '' : ' ') + cls[i];
|
||||
}
|
||||
|
||||
return ' class="' + out + '"';
|
||||
};
|
||||
|
||||
process([
|
||||
[/ class=\"([^\"]*)\"/gi, cleanClasses], // class attributes with quotes
|
||||
[/ class=(\w+)/gi, cleanClasses] // class attributes without quotes (IE)
|
||||
]);
|
||||
}
|
||||
|
||||
// Remove spans option
|
||||
if (ed.getParam('paste_remove_spans')) {
|
||||
process([
|
||||
/<\/?(span)[^>]*>/gi
|
||||
]);
|
||||
}
|
||||
|
||||
//console.log('After preprocess:' + h);
|
||||
|
||||
o.content = h;
|
||||
},
|
||||
|
||||
_insertText : function(content, bLinebreaks) {
|
||||
content = this.editor.dom.encode(content);
|
||||
/**
|
||||
* Various post process items.
|
||||
*/
|
||||
_postProcess : function(pl, o) {
|
||||
var t = this, ed = t.editor, dom = ed.dom, styleProps;
|
||||
|
||||
if (content && content.length > 0) {
|
||||
// Delete any highlighted text before pasting
|
||||
if (!this.editor.selection.isCollapsed())
|
||||
this.editor.execCommand("Delete");
|
||||
if (o.wordContent) {
|
||||
// Remove named anchors or TOC links
|
||||
each(dom.select('a', o.node), function(a) {
|
||||
if (!a.href || a.href.indexOf('#_Toc') != -1)
|
||||
dom.remove(a, 1);
|
||||
});
|
||||
|
||||
if (bLinebreaks) {
|
||||
// Special paragraph treatment
|
||||
if (this.editor.getParam("paste_create_paragraphs", true)) {
|
||||
var rl = this.editor.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');
|
||||
for (var i=0; i<rl.length; i+=2)
|
||||
content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]);
|
||||
if (t.editor.getParam('paste_convert_middot_lists', true))
|
||||
t._convertLists(pl, o);
|
||||
|
||||
content = content.replace(/\r\n\r\n/g, '</p><p>');
|
||||
content = content.replace(/\r\r/g, '</p><p>');
|
||||
content = content.replace(/\n\n/g, '</p><p>');
|
||||
// Process styles
|
||||
styleProps = ed.getParam('paste_retain_style_properties'); // retained properties
|
||||
|
||||
// Has paragraphs
|
||||
if ((pos = content.indexOf('</p><p>')) != -1) {
|
||||
this.editor.execCommand("Delete");
|
||||
// If string property then split it
|
||||
if (tinymce.is(styleProps, 'string'))
|
||||
styleProps = tinymce.explode(styleProps);
|
||||
|
||||
var node = this.editor.selection.getNode();
|
||||
// Retains some style properties
|
||||
each(dom.select('*', o.node), function(el) {
|
||||
var newStyle = {}, npc = 0, i, sp, sv;
|
||||
|
||||
// Get list of elements to break
|
||||
var breakElms = [];
|
||||
// Store a subset of the existing styles
|
||||
if (styleProps) {
|
||||
for (i = 0; i < styleProps.length; i++) {
|
||||
sp = styleProps[i];
|
||||
sv = dom.getStyle(el, sp);
|
||||
|
||||
do {
|
||||
if (node.nodeType == 1) {
|
||||
// Don't break tables and break at body
|
||||
if (node.nodeName == "TD" || node.nodeName == "BODY")
|
||||
break;
|
||||
|
||||
breakElms[breakElms.length] = node;
|
||||
}
|
||||
} while(node = node.parentNode);
|
||||
|
||||
var before = "", after = "</p>";
|
||||
before += content.substring(0, pos);
|
||||
|
||||
for (var i=0; i<breakElms.length; i++) {
|
||||
before += "</" + breakElms[i].nodeName + ">";
|
||||
after += "<" + breakElms[(breakElms.length-1)-i].nodeName + ">";
|
||||
}
|
||||
|
||||
before += "<p>";
|
||||
content = before + content.substring(pos+7) + after;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.editor.getParam("paste_create_linebreaks", true)) {
|
||||
content = content.replace(/\r\n/g, '<br />');
|
||||
content = content.replace(/\r/g, '<br />');
|
||||
content = content.replace(/\n/g, '<br />');
|
||||
if (sv) {
|
||||
newStyle[sp] = sv;
|
||||
npc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.editor.execCommand("mceInsertRawHTML", false, content);
|
||||
// Remove all of the existing styles
|
||||
dom.setAttrib(el, 'style', '');
|
||||
|
||||
if (styleProps && npc > 0)
|
||||
dom.setStyles(el, newStyle); // Add back the stored subset of styles
|
||||
else // Remove empty span tags that do not have class attributes
|
||||
if (el.nodeName == 'SPAN' && !el.className)
|
||||
dom.remove(el, true);
|
||||
});
|
||||
}
|
||||
|
||||
// Remove all style information or only specifically on WebKit to avoid the style bug on that browser
|
||||
if (ed.getParam("paste_remove_styles") || (ed.getParam("paste_remove_styles_if_webkit") && tinymce.isWebKit)) {
|
||||
each(dom.select('*[style]', o.node), function(el) {
|
||||
el.removeAttribute('style');
|
||||
el.removeAttribute('mce_style');
|
||||
});
|
||||
} else {
|
||||
if (tinymce.isWebKit) {
|
||||
// We need to compress the styles on WebKit since if you paste <img border="0" /> it will become <img border="0" style="... lots of junk ..." />
|
||||
// Removing the mce_style that contains the real value will force the Serializer engine to compress the styles
|
||||
each(dom.select('*', o.node), function(el) {
|
||||
el.removeAttribute('mce_style');
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_insertWordContent : function(content) {
|
||||
/**
|
||||
* Converts the most common bullet and number formats in Office into a real semantic UL/LI list.
|
||||
*/
|
||||
_convertLists : function(pl, o) {
|
||||
var dom = pl.editor.dom, listElm, li, lastMargin = -1, margin, levels = [], lastType, html;
|
||||
|
||||
// Convert middot lists into real semantic lists
|
||||
each(dom.select('p', o.node), function(p) {
|
||||
var sib, val = '', type, html, idx, parents;
|
||||
|
||||
// Get text node value at beginning of paragraph
|
||||
for (sib = p.firstChild; sib && sib.nodeType == 3; sib = sib.nextSibling)
|
||||
val += sib.nodeValue;
|
||||
|
||||
val = p.innerHTML.replace(/<\/?\w+[^>]*>/gi, '').replace(/ /g, '\u00a0');
|
||||
|
||||
// Detect unordered lists look for bullets
|
||||
if (/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o]\s*\u00a0*/.test(val))
|
||||
type = 'ul';
|
||||
|
||||
// Detect ordered lists 1., a. or ixv.
|
||||
if (/^__MCE_ITEM__\s*\w+\.\s*\u00a0{2,}/.test(val))
|
||||
type = 'ol';
|
||||
|
||||
// Check if node value matches the list pattern: o
|
||||
if (type) {
|
||||
margin = parseFloat(p.style.marginLeft || 0);
|
||||
|
||||
if (margin > lastMargin)
|
||||
levels.push(margin);
|
||||
|
||||
if (!listElm || type != lastType) {
|
||||
listElm = dom.create(type);
|
||||
dom.insertAfter(listElm, p);
|
||||
} else {
|
||||
// Nested list element
|
||||
if (margin > lastMargin) {
|
||||
listElm = li.appendChild(dom.create(type));
|
||||
} else if (margin < lastMargin) {
|
||||
// Find parent level based on margin value
|
||||
idx = tinymce.inArray(levels, margin);
|
||||
parents = dom.getParents(listElm.parentNode, type);
|
||||
listElm = parents[parents.length - 1 - idx] || listElm;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove middot or number spans if they exists
|
||||
each(dom.select('span', p), function(span) {
|
||||
var html = span.innerHTML.replace(/<\/?\w+[^>]*>/gi, '');
|
||||
|
||||
// Remove span with the middot or the number
|
||||
if (type == 'ul' && /^[\u2022\u00b7\u00a7\u00d8o]/.test(html))
|
||||
dom.remove(span);
|
||||
else if (/^[\s\S]*\w+\.( |\u00a0)*\s*/.test(html))
|
||||
dom.remove(span);
|
||||
});
|
||||
|
||||
html = p.innerHTML;
|
||||
|
||||
// Remove middot/list items
|
||||
if (type == 'ul')
|
||||
html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^[\u2022\u00b7\u00a7\u00d8o]\s*( |\u00a0)+\s*/, '');
|
||||
else
|
||||
html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^\s*\w+\.( |\u00a0)+\s*/, '');
|
||||
|
||||
// Create li and add paragraph data into the new li
|
||||
li = listElm.appendChild(dom.create('li', 0, html));
|
||||
dom.remove(p);
|
||||
|
||||
lastMargin = margin;
|
||||
lastType = type;
|
||||
} else
|
||||
listElm = lastMargin = 0; // End list element
|
||||
});
|
||||
|
||||
// Remove any left over makers
|
||||
html = o.node.innerHTML;
|
||||
if (html.indexOf('__MCE_ITEM__') != -1)
|
||||
o.node.innerHTML = html.replace(/__MCE_ITEM__/g, '');
|
||||
},
|
||||
|
||||
/**
|
||||
* This method will split the current block parent and insert the contents inside the split position.
|
||||
* This logic can be improved so text nodes at the start/end remain in the start/end block elements
|
||||
*/
|
||||
_insertBlockContent : function(ed, dom, content) {
|
||||
var parentBlock, marker, sel = ed.selection, last, elm, vp, y, elmHeight;
|
||||
|
||||
function select(n) {
|
||||
var r;
|
||||
|
||||
if (tinymce.isIE) {
|
||||
r = ed.getDoc().body.createTextRange();
|
||||
r.moveToElementText(n);
|
||||
r.collapse(false);
|
||||
r.select();
|
||||
} else {
|
||||
sel.select(n, 1);
|
||||
sel.collapse(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Insert a marker for the caret position
|
||||
this._insert('<span id="_marker"> </span>', 1);
|
||||
marker = dom.get('_marker');
|
||||
parentBlock = dom.getParent(marker, 'p,h1,h2,h3,h4,h5,h6,ul,ol,th,td');
|
||||
|
||||
// If it's a parent block but not a table cell
|
||||
if (parentBlock && !/TD|TH/.test(parentBlock.nodeName)) {
|
||||
// Split parent block
|
||||
marker = dom.split(parentBlock, marker);
|
||||
|
||||
// Insert nodes before the marker
|
||||
each(dom.create('div', 0, content).childNodes, function(n) {
|
||||
last = marker.parentNode.insertBefore(n.cloneNode(true), marker);
|
||||
});
|
||||
|
||||
// Move caret after marker
|
||||
select(last);
|
||||
} else {
|
||||
dom.setOuterHTML(marker, content);
|
||||
sel.select(ed.getBody(), 1);
|
||||
sel.collapse(0);
|
||||
}
|
||||
|
||||
dom.remove('_marker'); // Remove marker if it's left
|
||||
|
||||
// Get element, position and height
|
||||
elm = sel.getStart();
|
||||
vp = dom.getViewPort(ed.getWin());
|
||||
y = ed.dom.getPos(elm).y;
|
||||
elmHeight = elm.clientHeight;
|
||||
|
||||
// Is element within viewport if not then scroll it into view
|
||||
if (y < vp.y || y + elmHeight > vp.y + vp.h)
|
||||
ed.getDoc().body.scrollTop = y < vp.y ? y : y - vp.h + 25;
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts the specified contents at the caret position.
|
||||
*/
|
||||
_insert : function(h, skip_undo) {
|
||||
var ed = this.editor;
|
||||
|
||||
// First delete the contents seems to work better on WebKit
|
||||
if (!ed.selection.isCollapsed())
|
||||
ed.getDoc().execCommand('Delete', false, null);
|
||||
|
||||
// It's better to use the insertHTML method on Gecko since it will combine paragraphs correctly before inserting the contents
|
||||
ed.execCommand(tinymce.isGecko ? 'insertHTML' : 'mceInsertContent', false, h, {skip_undo : skip_undo});
|
||||
},
|
||||
|
||||
/**
|
||||
* This method will open the old style paste dialogs. Some users might want the old behavior but still use the new cleanup engine.
|
||||
*/
|
||||
_legacySupport : function() {
|
||||
var t = this, ed = t.editor;
|
||||
|
||||
if (content && content.length > 0) {
|
||||
// Cleanup Word content
|
||||
var bull = String.fromCharCode(8226);
|
||||
var middot = String.fromCharCode(183);
|
||||
// Register commands for backwards compatibility
|
||||
each(['mcePasteText', 'mcePasteWord'], function(cmd) {
|
||||
ed.addCommand(cmd, function() {
|
||||
ed.windowManager.open({
|
||||
file : t.url + (cmd == 'mcePasteText' ? '/pastetext.htm' : '/pasteword.htm'),
|
||||
width : parseInt(ed.getParam("paste_dialog_width", "450")),
|
||||
height : parseInt(ed.getParam("paste_dialog_height", "400")),
|
||||
inline : 1
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if (ed.getParam('paste_insert_word_content_callback'))
|
||||
content = ed.execCallback('paste_insert_word_content_callback', 'before', content);
|
||||
|
||||
var rl = ed.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\x93|\x94|\u201c|\u201d,",\x60|\x91|\x92|\u2018|\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');
|
||||
for (var i=0; i<rl.length; i+=2)
|
||||
content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]);
|
||||
|
||||
if (this.editor.getParam("paste_convert_headers_to_strong", false)) {
|
||||
content = content.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>', 'gi'), '<p><b>$1</b></p>');
|
||||
}
|
||||
|
||||
content = content.replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--");
|
||||
content = content.replace(new RegExp(bull + "(.*?)<BR>", "gi"), "<p>" + middot + "$1</p>");
|
||||
content = content.replace(new RegExp('<SPAN style="mso-list: Ignore">', 'gi'), "<span>" + bull); // Covert to bull list
|
||||
content = content.replace(/<o:p><\/o:p>/gi, "");
|
||||
content = content.replace(new RegExp('<br style="page-break-before: always;.*>', 'gi'), '-- page break --'); // Replace pagebreaks
|
||||
content = content.replace(/<!--([\s\S]*?)-->|<style>[\s\S]*?<\/style>/g, ""); // Word comments
|
||||
content = content.replace(/<(meta|link)[^>]+>/g, ""); // Header elements
|
||||
|
||||
if (this.editor.getParam("paste_remove_spans", true))
|
||||
content = content.replace(/<\/?span[^>]*>/gi, "");
|
||||
|
||||
if (this.editor.getParam("paste_remove_styles", true))
|
||||
content = content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)', 'gi'), "<$1$3");
|
||||
|
||||
content = content.replace(/<\/?font[^>]*>/gi, "");
|
||||
|
||||
// Strips class attributes.
|
||||
switch (this.editor.getParam("paste_strip_class_attributes", "all")) {
|
||||
case "all":
|
||||
content = content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3");
|
||||
break;
|
||||
|
||||
case "mso":
|
||||
content = content.replace(new RegExp('<(\\w[^>]*) class="?mso([^ |>]*)([^>]*)', 'gi'), "<$1$3");
|
||||
break;
|
||||
}
|
||||
|
||||
content = content.replace(new RegExp('href="?' + this._reEscape("" + document.location) + '', 'gi'), 'href="' + this.editor.documentBaseURI.getURI());
|
||||
content = content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3");
|
||||
content = content.replace(/<\\?\?xml[^>]*>/gi, "");
|
||||
content = content.replace(/<\/?\w+:[^>]*>/gi, "");
|
||||
content = content.replace(/-- page break --\s*<p> <\/p>/gi, ""); // Remove pagebreaks
|
||||
content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks
|
||||
|
||||
// content = content.replace(/\/? */gi, "");
|
||||
// content = content.replace(/<p> <\/p>/gi, '');
|
||||
|
||||
if (!this.editor.getParam('force_p_newlines')) {
|
||||
content = content.replace('', '' ,'gi');
|
||||
content = content.replace('</p>', '<br /><br />' ,'gi');
|
||||
}
|
||||
|
||||
if (!tinymce.isIE && !this.editor.getParam('force_p_newlines')) {
|
||||
content = content.replace(/<\/?p[^>]*>/gi, "");
|
||||
}
|
||||
|
||||
content = content.replace(/<\/?div[^>]*>/gi, "");
|
||||
|
||||
// Convert all middlot lists to UL lists
|
||||
if (this.editor.getParam("paste_convert_middot_lists", true)) {
|
||||
var div = ed.dom.create("div", null, content);
|
||||
|
||||
// Convert all middot paragraphs to li elements
|
||||
var className = this.editor.getParam("paste_unindented_list_class", "unIndentedList");
|
||||
|
||||
while (this._convertMiddots(div, "--list--")) ; // bull
|
||||
while (this._convertMiddots(div, middot, className)) ; // Middot
|
||||
while (this._convertMiddots(div, bull)) ; // bull
|
||||
|
||||
content = div.innerHTML;
|
||||
}
|
||||
|
||||
// Replace all headers with strong and fix some other issues
|
||||
if (this.editor.getParam("paste_convert_headers_to_strong", false)) {
|
||||
content = content.replace(/<h[1-6]> <\/h[1-6]>/gi, '<p> </p>');
|
||||
content = content.replace(/<h[1-6]>/gi, '<p><b>');
|
||||
content = content.replace(/<\/h[1-6]>/gi, '</b></p>');
|
||||
content = content.replace(/<b> <\/b>/gi, '<b> </b>');
|
||||
content = content.replace(/^( )*/gi, '');
|
||||
}
|
||||
|
||||
content = content.replace(/--list--/gi, ""); // Remove --list--
|
||||
|
||||
if (ed.getParam('paste_insert_word_content_callback'))
|
||||
content = ed.execCallback('paste_insert_word_content_callback', 'after', content);
|
||||
|
||||
// Insert cleaned content
|
||||
this.editor.execCommand("mceInsertContent", false, content);
|
||||
|
||||
if (this.editor.getParam('paste_force_cleanup_wordpaste', true)) {
|
||||
var ed = this.editor;
|
||||
|
||||
window.setTimeout(function() {
|
||||
ed.execCommand("mceCleanup");
|
||||
}, 1); // Do normal cleanup detached from this thread
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_reEscape : function(s) {
|
||||
var l = "?.\\*[](){}+^$:";
|
||||
var o = "";
|
||||
|
||||
for (var i=0; i<s.length; i++) {
|
||||
var c = s.charAt(i);
|
||||
|
||||
if (l.indexOf(c) != -1)
|
||||
o += '\\' + c;
|
||||
else
|
||||
o += c;
|
||||
}
|
||||
|
||||
return o;
|
||||
},
|
||||
|
||||
_convertMiddots : function(div, search, class_name) {
|
||||
var ed = this.editor, mdot = String.fromCharCode(183), bull = String.fromCharCode(8226);
|
||||
var nodes, prevul, i, p, ul, li, np, cp, li;
|
||||
|
||||
nodes = div.getElementsByTagName("p");
|
||||
for (i=0; i<nodes.length; i++) {
|
||||
p = nodes[i];
|
||||
|
||||
// Is middot
|
||||
if (p.innerHTML.indexOf(search) == 0) {
|
||||
ul = ed.dom.create("ul");
|
||||
|
||||
if (class_name)
|
||||
ul.className = class_name;
|
||||
|
||||
// Add the first one
|
||||
li = ed.dom.create("li");
|
||||
li.innerHTML = p.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--| ', "gi"), '');
|
||||
ul.appendChild(li);
|
||||
|
||||
// Add the rest
|
||||
np = p.nextSibling;
|
||||
while (np) {
|
||||
// If the node is whitespace, then
|
||||
// ignore it and continue on.
|
||||
if (np.nodeType == 3 && new RegExp('^\\s$', 'm').test(np.nodeValue)) {
|
||||
np = np.nextSibling;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (search == mdot) {
|
||||
if (np.nodeType == 1 && new RegExp('^o(\\s+| )').test(np.innerHTML)) {
|
||||
// Second level of nesting
|
||||
if (!prevul) {
|
||||
prevul = ul;
|
||||
ul = ed.dom.create("ul");
|
||||
prevul.appendChild(ul);
|
||||
}
|
||||
np.innerHTML = np.innerHTML.replace(/^o/, '');
|
||||
} else {
|
||||
// Pop the stack if we're going back up to the first level
|
||||
if (prevul) {
|
||||
ul = prevul;
|
||||
prevul = null;
|
||||
}
|
||||
// Not element or middot paragraph
|
||||
if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Not element or middot paragraph
|
||||
if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
cp = np.nextSibling;
|
||||
li = ed.dom.create("li");
|
||||
li.innerHTML = np.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--| ', "gi"), '');
|
||||
np.parentNode.removeChild(np);
|
||||
ul.appendChild(li);
|
||||
np = cp;
|
||||
}
|
||||
|
||||
p.parentNode.replaceChild(ul, p);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_clipboardHTML : function() {
|
||||
var div = document.getElementById('_TinyMCE_clipboardHTML');
|
||||
|
||||
if (!div) {
|
||||
var div = document.createElement('DIV');
|
||||
div.id = '_TinyMCE_clipboardHTML';
|
||||
|
||||
with (div.style) {
|
||||
visibility = 'hidden';
|
||||
overflow = 'hidden';
|
||||
position = 'absolute';
|
||||
width = 1;
|
||||
height = 1;
|
||||
}
|
||||
|
||||
document.body.appendChild(div);
|
||||
}
|
||||
|
||||
div.innerHTML = '';
|
||||
var rng = document.body.createTextRange();
|
||||
rng.moveToElementText(div);
|
||||
rng.execCommand('Paste');
|
||||
var html = div.innerHTML;
|
||||
div.innerHTML = '';
|
||||
return html;
|
||||
// Register buttons for backwards compatibility
|
||||
ed.addButton('pastetext', {title : 'paste.paste_text_desc', cmd : 'mcePasteText'});
|
||||
ed.addButton('pasteword', {title : 'paste.paste_word_desc', cmd : 'mcePasteWord'});
|
||||
ed.addButton('selectall', {title : 'paste.selectall_desc', cmd : 'selectall'});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+31
-37
@@ -1,42 +1,36 @@
|
||||
tinyMCEPopup.requireLangPack();
|
||||
|
||||
function saveContent() {
|
||||
if (document.forms[0].htmlSource.value == '') {
|
||||
var PasteTextDialog = {
|
||||
init : function() {
|
||||
this.resize();
|
||||
},
|
||||
|
||||
insert : function() {
|
||||
var h = tinyMCEPopup.dom.encode(document.getElementById('content').value), lines;
|
||||
|
||||
// Convert linebreaks into paragraphs
|
||||
if (document.getElementById('linebreaks').checked) {
|
||||
lines = h.split(/\r?\n/);
|
||||
if (lines.length > 1) {
|
||||
h = '';
|
||||
tinymce.each(lines, function(row) {
|
||||
h += '<p>' + row + '</p>';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
tinyMCEPopup.editor.execCommand('mceInsertClipboardContent', false, {content : h});
|
||||
tinyMCEPopup.close();
|
||||
return false;
|
||||
},
|
||||
|
||||
resize : function() {
|
||||
var vp = tinyMCEPopup.dom.getViewPort(window), el;
|
||||
|
||||
el = document.getElementById('content');
|
||||
|
||||
el.style.width = (vp.w - 20) + 'px';
|
||||
el.style.height = (vp.h - 90) + 'px';
|
||||
}
|
||||
};
|
||||
|
||||
tinyMCEPopup.execCommand('mcePasteText', false, {
|
||||
html : document.forms[0].htmlSource.value,
|
||||
linebreaks : document.forms[0].linebreaks.checked
|
||||
});
|
||||
|
||||
tinyMCEPopup.close();
|
||||
}
|
||||
|
||||
function onLoadInit() {
|
||||
tinyMCEPopup.resizeToInnerSize();
|
||||
|
||||
// Remove Gecko spellchecking
|
||||
if (tinymce.isGecko)
|
||||
document.body.spellcheck = tinyMCEPopup.getParam("gecko_spellcheck");
|
||||
|
||||
resizeInputs();
|
||||
}
|
||||
|
||||
var wHeight=0, wWidth=0, owHeight=0, owWidth=0;
|
||||
|
||||
function resizeInputs() {
|
||||
if (!tinymce.isIE) {
|
||||
wHeight = self.innerHeight-80;
|
||||
wWidth = self.innerWidth-17;
|
||||
} else {
|
||||
wHeight = document.body.clientHeight-80;
|
||||
wWidth = document.body.clientWidth-17;
|
||||
}
|
||||
|
||||
document.forms[0].htmlSource.style.height = Math.abs(wHeight) + 'px';
|
||||
document.forms[0].htmlSource.style.width = Math.abs(wWidth) + 'px';
|
||||
}
|
||||
|
||||
tinyMCEPopup.onInit.add(onLoadInit);
|
||||
tinyMCEPopup.onInit.add(PasteTextDialog.init, PasteTextDialog);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user