Initial commit
BIN
_cubecart/CubeCart-4.2.3.zip
Normal file
BIN
_cubecart/CubeCart-4.3.0.tgz
Normal file
230
_cubecart/CubeCart-4.3.0/Changelog.txt
Executable file
@@ -0,0 +1,230 @@
|
||||
CubeCart ChangeLog
|
||||
The original bug reports and ChangeLog can be viewed at http://bugs.cubecart.com/
|
||||
|
||||
CubeCart v4 - 4.3.0
|
||||
===================
|
||||
- 0001214: [Admin Control Panel] Post Delete Pagination (al) - resolved.
|
||||
- 0001180: [Checkout] Apostrophes showing up as a HTML character in the Delivery Details (al) - resolved.
|
||||
- 0001236: [Admin Control Panel] update order status fatal error (al) - resolved.
|
||||
- 0001209: [Interface] Bulk Email - Apostrophies problem in email subject (al) - resolved.
|
||||
- 0001247: [SEO] Blank Global Browser Title makes mess once Meta Data Behaviour is other than disabled (al) - resolved.
|
||||
- 0001222: [Languages] Missing and misplaced language element in the Edit Delivery page. (al) - resolved.
|
||||
- 0001241: [Interface] Store Search - Pagination problem on price sort for search results (al) - resolved.
|
||||
- 0001006: [Payment Gateways] Duplicate Paypal payments processed (al) - resolved.
|
||||
- 0001208: [Admin Control Panel] Bulk Email FCK-Editor images give bad URL (al) - resolved.
|
||||
- 0001154: [Admin Control Panel] Export issue, CSV is too limited as any product description containing commas destroys formatting (al) - resolved.
|
||||
- 0001219: [Admin Control Panel] Broken CubeCart CSV file in Export Catalogue (al) - resolved.
|
||||
- 0001203: [Catalogue] forgotPass email blocked, even when i tried to tweak (al) - resolved.
|
||||
- 0001248: [Admin Control Panel] Alternate images when removed are not updating img_idx table (al) - resolved.
|
||||
- 0001250: [Checkout] Cancel and Return to Street Tuned (al) - resolved.
|
||||
- 0001231: [Admin Control Panel] When deleting an option value sometimes the associated product options are not removed from products (al) - resolved.
|
||||
- 0001255: [Shipping Modules] Tax on shipping is counted once Add sales tax to customers who qualify is set to NO (al) - resolved.
|
||||
- 0001243: [Payment Gateways] Transactions not recorded using PayPal Standard (al) - resolved.
|
||||
- 0001232: [Admin Control Panel] FCK insert links not working (al) - resolved.
|
||||
- 0001259: [Interface] Internet Explorer no SSL padlock displayed on Registration page once Script/Bot Flood Control is used (al) - resolved.
|
||||
- 0001205: [Checkout] Back spaces in product code makes mess on cart pages (al) - resolved.
|
||||
- 0000794: [Interface] SO SLOW (al) - resolved.
|
||||
- 0001030: [Feature Request] Suggestion to speed up "Other customer also bought" feature (al) - resolved.
|
||||
- 0001178: [Checkout] After upgrading to 4.2.3, basket contents are lost by returning from step 3 to step 2 (al) - resolved.
|
||||
- 0001147: [Checkout] backing out of paypal checkout dumps cart (al) - resolved.
|
||||
- 0001142: [Admin Control Panel] sslSwitchInc.php is wrong (al) - resolved.
|
||||
- 0001213: [MySQL/Database] Related Products Query (al) - resolved.
|
||||
- 0001224: [Admin Control Panel] Possible to create categories whose parent category forms a loop (al) - resolved.
|
||||
- 0001235: [Admin Control Panel] FCK Editor Broken in Firefox 3 (al) - resolved.
|
||||
- 0001201: [Admin Control Panel] Rebuild of database fails when there is an image in a subfolder (al) - resolved.
|
||||
- 0001249: [Interface] global include closed.inc.php not used to show offLineContent when site is closed. (al) - resolved.
|
||||
- 0000997: [Payment Gateways] Credit Cards payment module validation requires Issue Date for Laser Card (martin) - resolved.
|
||||
- 0001225: [Admin Control Panel] Warning: set_time_limit() appears on Rebuild category product count page (al) - resolved.
|
||||
- 0001230: [Payment Gateways] call.inc.php line 114, variable $postal_code incorrect set (al) - resolved.
|
||||
- 0001216: [Interface] Bulk Email - Return Path not being used (martin) - resolved.
|
||||
- 0001192: [Catalogue] Shopping cart changes to allow floating point quantities (martin) - resolved.
|
||||
- 0001207: [Checkout] PayPal Direct Payment Only (al) - resolved.
|
||||
- 0001191: [Payment Gateways] PayPal - function logTransaction isn't defined anywhere? (martin) - resolved.
|
||||
- 0001189: [Payment Gateways] Card Capture showing XXX for all data fields (martin) - resolved.
|
||||
- 0001218: [Shipping Modules] Canada Post missing handling (al) - resolved.
|
||||
- 0001175: [Admin Control Panel] Admin - Maintenance - Rebuild & Recount - update Image Database produces error (al) - resolved.
|
||||
- 0001196: [Catalogue] Product options are not listed in a sequential order (martin) - resolved.
|
||||
- 0001220: [Interface] Tag error on login.tpl (martin) - resolved.
|
||||
- 0001186: [Catalogue] Buy buttons on products that are viewed in product category page do not work if they have product options assigned to them. (martin) - resolved.
|
||||
|
||||
CubeCart 4 - 4.2.3
|
||||
==================
|
||||
- 0001172: [SEO] Google toolbar users treated as spiders (martin) - resolved.
|
||||
- 0001170: [Admin Control Panel] fckblank.php file error (al) - resolved.
|
||||
- 0001169: [Basket] When using both text and regular options, sometimes some options are not saved to basket (martin) - resolved.
|
||||
- 0001166: [Catalogue] Sale Items still shown in Sale Items box, even if they are disabled one by one (al) - resolved.
|
||||
- 0001054: [Admin Control Panel] Quotes problem in order detail (al) - resolved.
|
||||
- 0001124: [Admin Control Panel] Security Warning order command (al) - resolved.
|
||||
- 0001152: [Interface] Login "Remember Me" function doesn't work (martin) - resolved.
|
||||
- 0001122: [Admin Control Panel] Missing password verification on additional admin setup. (al) - resolved.
|
||||
- 0001123: [Admin Control Panel] Review email not handling apostrophies. (al) - resolved.
|
||||
- 0001134: [Checkout] country is lost (martin) - resolved.
|
||||
- 0001053: [Languages] Purge on languages (al) - resolved.
|
||||
- 0001050: [Admin Control Panel] IP lookup window doesn't resize. (al) - resolved.
|
||||
- 0001084: [Checkout] Product names entities in order complete email (al) - resolved.
|
||||
- 0001157: [Interface] Ampersands problem in tell a friend emails (al) - resolved.
|
||||
- 0001116: [Interface] If customer tries to update addres they receive Error Message: "Telephone numbers must be numeric only." (al) - resolved.
|
||||
- 0001168: [Interface] XSS Vulnerability (Helpdesk Ticket 49436) (martin) - resolved.
|
||||
- 0001107: [Basket] Items not being added to Basket. (al) - resolved.
|
||||
- 0001140: [Interface] Registration page Required Fields Error (martin) - resolved.
|
||||
- 0001118: [Catalogue] Hide Sale Items link in categories menu if display empty categories set to no. (martin) - resolved.
|
||||
- 0001098: [Admin Control Panel] Image Management - hash comparison some images are not found/displayed (martin) - resolved.
|
||||
- 0001150: [Admin Control Panel] Changing a category's priority (sort order) can affect multiple categories when not using drag and drop. (martin) - resolved.
|
||||
- 0001039: [Admin Control Panel] Single quota in image name breaks filemanager buildDatabase fn (martin) - resolved.
|
||||
- 0001094: [Interface] Wrong image relative path on Win servers once upgraded to latest version (al) - resolved.
|
||||
- 0001064: [Catalogue] catagory product count goes up after editing a product. (al) - resolved.
|
||||
- 0001110: [Catalogue] Gift Certificate (Min: Max:) (al) - resolved.
|
||||
- 0001125: [Payment Gateways] HSBC Gateway - Secure Payments (martin) - resolved.
|
||||
- 0001129: [Catalogue] Unable to sort by price/name for search results (martin) - resolved.
|
||||
- 0001114: [Admin Control Panel] Image Management - images in folders cannot be deleted (al) - resolved.
|
||||
- 0001130: [Interface] Search results can't be ordered (martin) - resolved.
|
||||
- 0001149: [SEO] Apostrophies rendered incorrectly in meta description (al) - resolved.
|
||||
- 0001049: [Admin Control Panel] Security Warning Page on admin order page (martin) - resolved.
|
||||
- 0001138: [Admin Control Panel] Call to undefined function: substr_compare() (martin) - resolved.
|
||||
- 0001136: [Admin Control Panel] Manage images in Admin CP does not delete them. (martin) - resolved.
|
||||
- 0001133: [Basket] -ve product qualtitys & add product by product code issue (martin) - resolved.
|
||||
- 0001109: [Catalogue] Advanced Search causes SQL errors (al) - resolved.
|
||||
- 0001111: [Admin Control Panel] problem Security Warning Page on admin order page (al) - closed.
|
||||
- 0000895: [Checkout] Google checkout and shipping rates (al) - closed.
|
||||
- 0001075: [Admin Control Panel] Print Packing Slip - Extra Footer HTML (martin) - closed.
|
||||
- 0001071: [Admin Control Panel] notes to customer field in order screen not holding its value (martin) - closed.
|
||||
- 0001067: [Catalogue] Advanced Search Error (martin) - closed.
|
||||
- 0001062: [Languages] Adding Review: Confirmation text has typo (martin) - closed.
|
||||
- 0001060: [Catalogue] Product Reviews - Popup alert wrong text (martin) - closed.
|
||||
- 0001048: [Payment Gateways] 'LANG_PAYMENT' is assigned twice in ROOT/includes/content/gateway.inc.php (martin) - closed.
|
||||
- 0001041: [Catalogue] Static directory separator which can break windows installs (al) - closed.
|
||||
- 0001034: [Catalogue] Missing slashes in URL once $GLOBALS['rootRel'] is a slash (martin) - closed.
|
||||
- 0000934: [Payment Gateways] WorldPay missing RETURN URL (al) - closed.
|
||||
- 0000914: [Admin Control Panel] Per Category International shipping costs issue (martin) - closed.
|
||||
- 0001077: [Feature Request] Display Trail in Admin CP (martin) - closed.
|
||||
- 0001083: [Catalogue] Fix to 0000823 breaks (some?) searchs in 4.2.2 (martin) - closed.
|
||||
- 0001086: [Install] County/State/Zone information of CC3 data incompatible with CC4 tax module (martin) - closed.
|
||||
- 0001088: [Admin Control Panel] Cannot delete images using image manager on Windows servers (al) - closed.
|
||||
- 0001045: [Admin Control Panel] Inventory export to cubecart csv does not work properly (al) - closed.
|
||||
- 0001089: [Admin Control Panel] Can delete image even when they are used in homepage (al) - closed.
|
||||
- 0001101: [Licence Issues] Read-only admin access for 7 days if dial-home fails. (al) - closed.
|
||||
- 0001097: [Admin Control Panel] Publish and Unpublish review asks user wrong question (martin) - closed.
|
||||
- 0001095: [Checkout] Google CO Duplicate Data (al) - closed.
|
||||
- 0001093: [Basket] Product Options Problem (martin) - closed.
|
||||
- 0001099: [Catalogue] Bad character coding issue at Product options (martin) - closed.
|
||||
- 0000567: [Shipping Modules] USPS International shipping problem (al) - closed.
|
||||
- 0001091: [Admin Control Panel] Add SELECT TAX in admin product details page to Tax drop down (martin) - closed.
|
||||
- 0001090: [Interface] Product initial ordering on category page using order by Name or Price is descending instead of ascending (martin) - closed.
|
||||
|
||||
CubeCart 4 - 4.2.2
|
||||
==================
|
||||
- 0000945: [Languages] Messed emails content (al) - closed.
|
||||
- 0000964: [Catalogue] Tell a friend value="" missing twice (martin) - closed.
|
||||
- 0000966: [SEO] missing SEO URL in function addByCode($code) (martin) - closed.
|
||||
- 0000965: [Catalogue] Gift Certificate (Prices include Tax:) (martin) - closed.
|
||||
- 0000961: [Catalogue] Advanced Search - How can you search without a search button? (martin) - closed.
|
||||
- 0000952: [Basket] CRASH with product options with text-area because of illegal characters (martin) - closed.
|
||||
- 0000970: [Basket] Voucher Balance not added back on empty basket (martin) - closed.
|
||||
- 0000967: [Admin Control Panel] Image errors in filemanager (martin) - closed.
|
||||
- 0000968: [Admin Control Panel] Tick box needed (Do not resize image:) (martin) - closed.
|
||||
- 0000978: [Interface] 1st Vulnerability XSS (martin) - closed.
|
||||
- 0000990: [Admin Control Panel] Missing <tr> (martin) - closed.
|
||||
- 0000988: [Admin Control Panel] Permissions on update prices (al) - closed.
|
||||
- 0000983: [Languages] German Language Issue (martin) - closed.
|
||||
- 0000982: [Checkout] Customer comments erased (martin) - closed.
|
||||
- 0000979: [Catalogue] Search failure on non-existant terms -- MySQL Error (martin) - closed.
|
||||
- 0000940: [Catalogue] Single quota in product otions becomes &0000039; (martin) - closed.
|
||||
- 0000994: [Admin Control Panel] Import Catalogue: 'Erase and replace the existing data' option doesn't clear product categories (al) - closed.
|
||||
- 0000996: [Skins] wrong template call in search.tpl (martin) - closed.
|
||||
- 0000998: [Admin Control Panel] modules/common.inc.php issue (martin) - closed.
|
||||
- 0000997: [Payment Gateways] Credit Cards payment module validation requires Issue Date for Laser Card (martin) - closed.
|
||||
- 0000995: [Basket] Error adding to cart (martin) - closed.
|
||||
- 0001004: [Payment Gateways] PayJunction transfer.inc.php syntax error (martin) - closed.
|
||||
- 0001002: [Payment Gateways] "Declined" doesn't give payment option (martin) - closed.
|
||||
- 0001000: [Admin Control Panel] typo in file admin/sources/orders/index.inc.php (martin) - closed.
|
||||
- 0000999: [Basket] Characters problem (martin) - closed.
|
||||
- 0001007: [Catalogue] Advanced search ignores category and returns all (martin) - closed.
|
||||
- 0001005: [Admin Control Panel] Manage Images > CONTINUE TO DELETE? (martin) - closed.
|
||||
- 0001019: [Checkout] Orders - Subtotal doesn't add up / products appearing that weren't wanted (martin) - closed.
|
||||
- 0001012: [Basket] Problem with "Product options must be selected" (martin) - closed.
|
||||
- 0001013: [Payment Gateways] Nochex_APC no download links emails (martin) - closed.
|
||||
- 0001018: [Admin Control Panel] Nonexistent inventory table column Title in admin View Products filter dropdown (martin) - closed.
|
||||
- 0001016: [Interface] Search too Vague (martin) - closed.
|
||||
- 0001021: [Languages] Potential headers already sent problem (martin) - closed.
|
||||
- 0001020: [Catalogue] Category count include hidden (martin) - closed.
|
||||
- 0001022: [Admin Control Panel] Admin Add/Edit Products - Missing <tr> tag (martin) - closed.
|
||||
- 0001015: [Admin Control Panel] Category reordering (martin) - closed.
|
||||
- 0001008: [Payment Gateways] Paypal direct payment not sending customers address to paypal (al) - closed.
|
||||
- 0001024: [Catalogue] bug 0000940 not fixed as listed (martin) - closed.
|
||||
- 0001010: [Catalogue] Incorrect product count on categories with disabled items (martin) - closed.
|
||||
- 0001025: [Install] Compat-test fails to detect gd 2 (martin) - closed.
|
||||
- 0001026: [Admin Control Panel] Html entities causing Add Order customer menu to break (martin) - closed.
|
||||
- 0001031: [Catalogue] Dates in reviews messed up (martin) - closed.
|
||||
- 0001032: [Languages] Review issues with German Language (martin) - closed.
|
||||
- 0000984: [Admin Control Panel] Google Base Updates - closed.
|
||||
|
||||
CubeCart 4 - 4.2.1
|
||||
==================
|
||||
- 0000962: [Catalogue] Gift certificate page can be seen if there disabled when you go to the url (al) - resolved.
|
||||
- 0000959: [Catalogue] Change password (lack of error checking) (martin) - resolved.
|
||||
- 0000958: [Skins] Wrong html code (al) - resolved.
|
||||
- 0000954: [Admin Control Panel] Check Manage Images (martin) - resolved.
|
||||
- 0000826: [Payment Gateways] Paypal Pro still giving problems (al) - resolved.
|
||||
- 0000924: [Checkout] Paypal PRo Direct Payment empties the basket on checkout (al) - resolved.
|
||||
- 0000925: [Interface] sslSwitch.inc.php issue on Shared SSL (martin) - resolved.
|
||||
- 0000937: [Catalogue] Manage Images (martin) - resolved.
|
||||
- 0000940: [Catalogue] Single quota in product otions becomes &0000039; (martin) - resolved.
|
||||
- 0000944: [Admin Control Panel] Fatal error: Call to undefined function mcrypt_module_open() (martin) - resolved.
|
||||
- 0000939: [Languages] Spelling mistake (martin) - resolved.
|
||||
- 0000928: [Admin Control Panel] View products - manage images (martin) - resolved.
|
||||
- 0000927: [Checkout] PayPal Website Payments Pro (Sale) is unusable. (martin) - resolved.
|
||||
- 0000929: [Skins] Product Option Text Assignment (martin) - resolved.
|
||||
- 0000931: [Admin Control Panel] Import Catalogue does no file checking (martin) - resolved.
|
||||
- 0000922: [Shipping Modules] UPS Issue (Possibly) (martin) - resolved.
|
||||
- 0000920: [Skins] Carreta Soft missing asterix in reg form next to county text input (martin) - resolved.
|
||||
- 0000926: [Payment Gateways] Authorize.net AIM Merchant Id (martin) - resolved.
|
||||
- 0000923: [Admin Control Panel] /admin/sources/products/extraImgs.inc.php Bugs (martin) - resolved.
|
||||
- 0000918: [Admin Control Panel] SQL Duplicate Key Error Editing Homepage Text on Windows Server (martin) - resolved.
|
||||
- 0000915: [Admin Control Panel] Admin image still broke (martin) - resolved.
|
||||
- 0000914: [Admin Control Panel] Per Category International shipping costs issue (martin) - resolved.
|
||||
- 0000913: [Admin Control Panel] Product Options on Add/Edit (few issues) (martin) - resolved.
|
||||
- 0000919: [Shipping Modules] Missing ( in ups shipping module (martin) - resolved.
|
||||
|
||||
CubeCart 4 - 4.2.0
|
||||
==================
|
||||
- 0000912: [Languages] language/it/includes/content/gateway.inc.php issue (martin) - resolved.
|
||||
- 0000909: [Skins] incorrect alignment of shopping cart prices and totals (martin) - resolved.
|
||||
- 0000910: [Checkout] Customer Account Registered When Choosing Not to Register an Account (martin) - resolved.
|
||||
- 0000908: [Interface] Flash basket missing under SEO (al) - resolved.
|
||||
- 0000906: [Catalogue] item-count shows inactive products (martin) - resolved.
|
||||
- 0000884: [Catalogue] Advanced Search issues (martin) - resolved.
|
||||
- 0000904: [Catalogue] Gift certificate (no error messages) (martin) - resolved.
|
||||
- 0000898: [Skins] {LANG_TITLE_DESC} missing (martin) - resolved.
|
||||
- 0000901: [Interface] Site document names in default language instead of foreign ones (martin) - resolved.
|
||||
- 0000891: [SEO] ?&page=x in URL (martin) - resolved.
|
||||
- 0000873: [Catalogue] Disabled product still showing in some store areas... (martin) - resolved.
|
||||
- 0000896: [Skins] Category box items icons are not displaying correctly (martin) - resolved.
|
||||
- 0000897: [Admin Control Panel] Sale price is not adjustable (martin) - resolved.
|
||||
- 0000876: [Skins] Template assignment in unsubscribe.inc.php (martin) - resolved.
|
||||
- 0000900: [Skins] Hardcoded english text in viewProd.tpl (martin) - resolved.
|
||||
- 0000886: [Admin Control Panel] 1 admin image left to fix (martin) - resolved.
|
||||
- 0000868: [Checkout] Gift Certificate "allowed uses" doesn't reset if removed (martin) - resolved.
|
||||
- 0000874: [Catalogue] Navigation quirk when adding a searched item to basket. (martin) - resolved.
|
||||
- 0000882: [Interface] Sale price issue (martin) - resolved.
|
||||
- 0000888: [Admin Control Panel] Ghost product reviews (martin) - resolved.
|
||||
- 0000887: [Admin Control Panel] Customer with 2 orders deleted, orders stay, There are no orders in the database. (martin) - resolved.
|
||||
- 0000877: [Skins] HTML ID used where a CLASS should be used. (martin) - resolved.
|
||||
- 0000880: [Skins] XHTML issues on registration page (martin) - resolved.
|
||||
- 0000881: [Interface] Required attribute "type" not specified in SCRIPT tag (martin) - resolved.
|
||||
- 0000883: [Admin Control Panel] Unable to empty product fields (martin) - resolved.
|
||||
- 0000834: [MySQL/Database] slow SQL queries that do not return any results (martin) - resolved.
|
||||
- 0000842: [Catalogue] Hidden category products shown otherwhere (martin) - resolved.
|
||||
- 0000849: [Admin Control Panel] Staff comments in the email that the customer receives (martin) - resolved.
|
||||
- 0000850: [Interface] Front End Look Back Bug (martin) - resolved.
|
||||
- 0000851: [Languages] Single quoute in $lang['admin_common']['delete_q'] breaks Javascript on DELETE decision in admin side (martin) - resolved.
|
||||
- 0000855: [Admin Control Panel] Unable to decrease prices/sale prices by fixed amount using Update Prices by Category in product area (martin) - resolved.
|
||||
- 0000858: [Languages] Missing label in French lang file tellafriend.inc.php (martin) - resolved.
|
||||
- 0000859: [Admin Control Panel] Images can't be deleted - on Windows servers when subfolders are used (martin) - resolved.
|
||||
- 0000862: [Catalogue] Products in Imported Products category are search able (martin) - resolved.
|
||||
- 0000864: [Shipping Modules] PER CATEGORY - Using country not listed in module settings provides free shipping (martin) - resolved.
|
||||
- 0000871: [Catalogue] Products also bought missing price (martin) - resolved.
|
||||
- 0000870: [Skins] Misplaced close form element (martin) - resolved.
|
||||
- 0000865: [Skins] Internet Explorer issue to the 10th product in Popular products box (martin) - resolved.
|
||||
|
||||
==================
|
||||
A more extensive ChangeLog can be found at http://bugs.cubecart.com/changelog_page.php
|
||||
34
_cubecart/CubeCart-4.3.0/Credits.txt
Executable file
@@ -0,0 +1,34 @@
|
||||
+----------------------
|
||||
|CubeCart v4 Credits
|
||||
+----------------------
|
||||
|
||||
Developed in the UK by:
|
||||
Al Brookbanks
|
||||
Martin Purcell
|
||||
|
||||
Contributions by:
|
||||
Paula Baker - Caretta Skins
|
||||
Estelle Winterflood - Improved Tax Functionality
|
||||
Joseph Fonseka - Search Engine Optimisation
|
||||
Milos Homola - Many bug fixes and general tweaks :)
|
||||
Bill Wheeler - Category caching and feature enhancement
|
||||
|
||||
In particular Al would like to thank...
|
||||
Bill Wheeler - For lending me his code spectacles and light bulbs.
|
||||
Milos Homola - For continual support, bug fixes etc.. :P
|
||||
William Renfrew - For general advice/help.
|
||||
Slim Devices - For allowing us to have MegaZigabytes of music via our SqueezeBox 2 in the office. (Fixed by Martin)
|
||||
Ubuntu - For creating a fantastic Linux distro used during development.
|
||||
Beer, Curry & Pizza - Goes without saying really...
|
||||
The Missus - For understanding late nights and stress.
|
||||
All our comunity members esppecially our moderators and customers.
|
||||
|
||||
|
||||
Martin would like to thank...
|
||||
Gem Dienel - The 'missus' :)
|
||||
Billy Lunn - Because if I give HIM a credit in MY work, he's obliged to return the favour on the next album sleeve (remember Bill, I designed your logo!) ;)
|
||||
Apple, Inc - 20" Core 2 Duo iMac & MacBook Black. And, very soon, an iPhone. Need I say more? :D
|
||||
Jaegermeister - For allowing me to 'wind down' on a Friday night. In the pub.
|
||||
Toffoc - Why, oh why, is this only available in Wales?
|
||||
Logitech - For allowing me to beta test the new SqueezeBox Duet.
|
||||
#php on EFnet - For being a good laugh, and an occasional source of help ;)
|
||||
207
_cubecart/CubeCart-4.3.0/Read Me.txt
Executable file
@@ -0,0 +1,207 @@
|
||||
+--------------------------------------------------------
|
||||
| CubeCart v4 Install / Upgrade Instructions
|
||||
+--------------------------------------------------------
|
||||
|
||||
Contents:
|
||||
|
||||
1. Install Instructions
|
||||
2. Upgrade Instructions - version 4 to latest version 4
|
||||
3. Upgrade Instructions - version 3 to latest version 4
|
||||
4. Installing IonCube Loaders
|
||||
|
||||
|
||||
Requirements:
|
||||
|
||||
PHP 5.1.0 ≥ (Scripting Language)
|
||||
MySQL 4.1 ≥ (Database Server) - MySQL 5 supported.
|
||||
GD (Image Library) recommended.
|
||||
Linux / Unix (recommended) or Windows* hosting account required.
|
||||
Curl with SSL support required for some shipping/payment modules.
|
||||
|
||||
* ZendOptimizer or Ioncube will need to be installed on WIndows servers in order to run
|
||||
CubeCart v4. On Linux/Unix servers ZendOptimizer is not required but the hosting account
|
||||
must be able to load IonCube loader files.
|
||||
|
||||
|
||||
|
||||
+--------------------------------------------------------
|
||||
| 1. Install Instructions
|
||||
+--------------------------------------------------------
|
||||
|
||||
These install instructions assume you have a web hosting account
|
||||
meeting CubeCart's requirements with a MySQL database already created.
|
||||
|
||||
a. Upload the entire contents of this folder to the desired
|
||||
location within the public HTML folder of your hosting account.
|
||||
|
||||
Examples:
|
||||
|
||||
/public_html
|
||||
/www/store
|
||||
/htdocs/shop
|
||||
|
||||
b. From your browser type in the website address to the files which
|
||||
have just been uploaded to and load it.
|
||||
|
||||
Examples:
|
||||
|
||||
http://www.example.com/
|
||||
http://store.example.com/
|
||||
http://www.example.com/shop/
|
||||
|
||||
c. Ensure that the correct file permissions are set on the files. these should be:
|
||||
|
||||
Writable (0777):
|
||||
images/uploads/
|
||||
images/uploads/thumbs/
|
||||
includes/extra/
|
||||
cache/
|
||||
|
||||
d. If all files have been uploaded successfully and the hosting account
|
||||
is compatible a screen should be presented with the options to install
|
||||
or upgrade. Please select "Install CubeCart" and follow the on screen
|
||||
instructions.
|
||||
|
||||
e. Once complete please delete the /setup folder to keep your store
|
||||
secure.
|
||||
|
||||
f. After visiting the front or back end of the store you may need to follow
|
||||
part 4 of this read me file.
|
||||
|
||||
For support please visit http://www.cubecart.com
|
||||
|
||||
|
||||
+--------------------------------------------------------
|
||||
| 2. Upgrade Instructions - version 4.x to latest version 4
|
||||
+--------------------------------------------------------
|
||||
|
||||
a. Take a FULL backup of your existing files and database and check that
|
||||
it is complete. This is critical in case the upgrade process fails or
|
||||
there is an error.
|
||||
|
||||
b. Upload the entire contents of this folder over your existing files
|
||||
replacing all existing ones.
|
||||
|
||||
IMPORTANT: If you renamed your admin folder or admin.php file you must do this prior
|
||||
to uploading the new files ad your store will work as before.
|
||||
|
||||
c. Once that has completed in full please browse to the setup folder of your store.
|
||||
|
||||
Examples:
|
||||
|
||||
http://www.example.com/setup/
|
||||
http://store.example.com/setup/
|
||||
http://www.example.com/shop/setup/
|
||||
|
||||
N.B. FTP can time out so please check the FTP log if available to make sure it
|
||||
completed successfully.
|
||||
|
||||
d. If all files have uploaded successfully the setup page should load. Please select
|
||||
"Upgrade CubeCart" and follow the on screen instructions.
|
||||
|
||||
e. Once complete please delete the /setup folder to keep your store
|
||||
secure.
|
||||
|
||||
f. After visiting the front or back end of the store you may need to follow
|
||||
part 4 of this read me file.
|
||||
|
||||
For support please visit http://www.cubecart.com
|
||||
|
||||
+--------------------------------------------------------
|
||||
| 3. Upgrade Instructions - version 3.0.x to latest version 4
|
||||
+--------------------------------------------------------
|
||||
|
||||
a. Take a FULL backup of your existing files and database and check that
|
||||
it is complete. This is critical in case the upgrade process fails or
|
||||
there is an error.
|
||||
|
||||
b. Please delete the following folders and files:
|
||||
|
||||
Folders:
|
||||
|
||||
/admin/
|
||||
/classes/
|
||||
/docs/
|
||||
/extra/
|
||||
/js/
|
||||
/language/
|
||||
/modules/
|
||||
/pear/
|
||||
/skins/
|
||||
|
||||
Files:
|
||||
|
||||
/cart.php
|
||||
/confirmed.php
|
||||
/download.php
|
||||
/offLine.php
|
||||
/switch.php
|
||||
|
||||
This should just leave the following folders:
|
||||
/images
|
||||
/includes
|
||||
|
||||
c. Upload the entire contents of this folder over the remaining files
|
||||
replacing all existing ones.
|
||||
|
||||
d. Please make sure the following folders are writable by the web browser.
|
||||
|
||||
/cache
|
||||
/includes/extra
|
||||
|
||||
If you have a Windows Server please ignore this step. If you have a Linux/Unix
|
||||
environment please make sure these have a chmod value of 0777 or 0775.
|
||||
|
||||
e. Once that has completed in full please browse to the setup folder of your store.
|
||||
|
||||
Examples:
|
||||
|
||||
http://www.example.com/setup/
|
||||
http://store.example.com/setup/
|
||||
http://www.example.com/shop/setup/
|
||||
|
||||
N.B. FTP can time out so please check the FTP log if available to make sure it
|
||||
completed successfully.
|
||||
|
||||
f. If all files have uploaded successfully the setup page should load. Please select
|
||||
"Upgrade CubeCart" and follow the on screen instructions.
|
||||
|
||||
g. Once complete please delete the /setup folder to keep your store
|
||||
secure.
|
||||
|
||||
h. After visiting the front or back-end of the store you may need to follow
|
||||
part 4 of this read me file.
|
||||
|
||||
For support please visit http://www.cubecart.com
|
||||
|
||||
+--------------------------------------------------------
|
||||
| 4. Installing IonCube Loaders
|
||||
+--------------------------------------------------------
|
||||
If your server doesn't have the Zend Optimizer you may be
|
||||
prompted with a message such as:
|
||||
|
||||
"Site error: the file /path/to/file_enc_ion.php requires
|
||||
the ionCube PHP Loader ioncube_loader_xxx_x.x.so to be
|
||||
installed by the site administrator."
|
||||
|
||||
To do this follow this please follow these instructions.
|
||||
|
||||
a. Go to http://www.ioncube.com/loaders.php
|
||||
|
||||
b. Download the suitable archive to your local machine.
|
||||
|
||||
c. Upload the suitable loader file from the extracted
|
||||
archive to the /ioncube folder.
|
||||
|
||||
e.g. /ioncube/ioncube_loader_xxx_x.x.so
|
||||
|
||||
|
||||
Troubleshooting:
|
||||
Please beware that if the loader you have downloaded fails
|
||||
there may be an alternative one for different server architectures.
|
||||
|
||||
e.g. Linux (x86) vs Linux (x86-64)
|
||||
|
||||
For support please visit http://www.cubecart.com
|
||||
|
||||
+--------------------------------------------------------
|
||||
46
_cubecart/CubeCart-4.3.0/admin.php
Executable file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/v4-software-license
|
||||
+--------------------------------------------------------------------------
|
||||
| admin.php
|
||||
| ========================================
|
||||
| Selects which encoding method to use
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
require_once 'ini.inc.php';
|
||||
require_once 'includes'.CC_DS.'global.inc.php';
|
||||
require_once 'includes'.CC_DS.'functions.inc.php';
|
||||
|
||||
## If you are behind a proxy, please configure the fields below
|
||||
## Examples below are for GoDaddy hosting
|
||||
$glob['proxyEnable']= false;
|
||||
$glob['proxyHost'] = ''; // e.g. proxy.shr.secureserver.net
|
||||
$glob['proxyPort'] = ''; // e.g. 3128
|
||||
$glob['proxyUser'] = ''; // leave this empty for godaddy
|
||||
$glob['proxyPass'] = ''; // leave this empty for godaddy
|
||||
|
||||
## Load the encoded file
|
||||
if ($glob['encoder'] == 'zend') {
|
||||
require_once 'admin_enc_zend.php';
|
||||
} else {
|
||||
require_once 'admin_enc_ion.php';
|
||||
}
|
||||
?>
|
||||
BIN
_cubecart/CubeCart-4.3.0/admin/images/0.gif
Executable file
|
After Width: | Height: | Size: 49 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/1.gif
Executable file
|
After Width: | Height: | Size: 49 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/back.gif
Executable file
|
After Width: | Height: | Size: 216 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/background/tdTitle.gif
Executable file
|
After Width: | Height: | Size: 691 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/buttons/new.gif
Executable file
|
After Width: | Height: | Size: 132 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/calc.gif
Executable file
|
After Width: | Height: | Size: 107 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/ccAdminLogo.gif
Executable file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
_cubecart/CubeCart-4.3.0/admin/images/ccAdminLogoLrg.gif
Executable file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
_cubecart/CubeCart-4.3.0/admin/images/del.gif
Executable file
|
After Width: | Height: | Size: 141 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/down.gif
Executable file
|
After Width: | Height: | Size: 73 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/file.gif
Executable file
|
After Width: | Height: | Size: 229 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/folder.gif
Executable file
|
After Width: | Height: | Size: 225 B |
3
_cubecart/CubeCart-4.3.0/admin/images/index.php
Executable file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
die("Access Denied");
|
||||
?>
|
||||
BIN
_cubecart/CubeCart-4.3.0/admin/images/info.gif
Executable file
|
After Width: | Height: | Size: 588 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/largeWarning.gif
Executable file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
_cubecart/CubeCart-4.3.0/admin/images/no_del.gif
Executable file
|
After Width: | Height: | Size: 135 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/productIcon0.gif
Executable file
|
After Width: | Height: | Size: 589 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/productIcon1.gif
Executable file
|
After Width: | Height: | Size: 588 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/progress.gif
Executable file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
_cubecart/CubeCart-4.3.0/admin/images/px.gif
Executable file
|
After Width: | Height: | Size: 43 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/rating/0.5.gif
Executable file
|
After Width: | Height: | Size: 358 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/rating/0.gif
Executable file
|
After Width: | Height: | Size: 172 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/rating/1.gif
Executable file
|
After Width: | Height: | Size: 364 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/selectAll.gif
Executable file
|
After Width: | Height: | Size: 59 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/statsBar.gif
Executable file
|
After Width: | Height: | Size: 49 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/type0.gif
Executable file
|
After Width: | Height: | Size: 335 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/type1.gif
Executable file
|
After Width: | Height: | Size: 582 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/type2.gif
Executable file
|
After Width: | Height: | Size: 169 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/up.gif
Executable file
|
After Width: | Height: | Size: 75 B |
BIN
_cubecart/CubeCart-4.3.0/admin/images/warning.gif
Executable file
|
After Width: | Height: | Size: 223 B |
30
_cubecart/CubeCart-4.3.0/admin/includes/currencyVars.inc.php
Executable file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/v4-software-license
|
||||
+--------------------------------------------------------------------------
|
||||
| currencyVars.inc.php
|
||||
| ========================================
|
||||
| Currency Vars
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
if (!defined('CC_INI_SET')) die("Access Denied");
|
||||
$query = sprintf("SELECT value, symbolLeft, symbolRight, decimalPlaces, name FROM %sCubeCart_currencies WHERE code=%s", $glob['dbprefix'], $db->mySQLSafe($config['defaultCurrency']));
|
||||
$currencyVars = $db->select($query);
|
||||
?>
|
||||
38
_cubecart/CubeCart-4.3.0/admin/includes/footer.inc.php
Executable file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/v4-software-license
|
||||
+--------------------------------------------------------------------------
|
||||
| footer.inc.php
|
||||
| ========================================
|
||||
| Admin Footer
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
if (!defined('CC_INI_SET')) die("Access Denied");
|
||||
if (isset($GLOBALS[CC_ADMIN_SESSION_NAME]) && !isset($skipFooter)) {
|
||||
?>
|
||||
</div>
|
||||
<!-- start wrapping table -->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- end wrapping table -->
|
||||
<?php } ?>
|
||||
</body>
|
||||
</html>
|
||||
76
_cubecart/CubeCart-4.3.0/admin/includes/header.inc.php
Executable file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/v4-software-license
|
||||
+--------------------------------------------------------------------------
|
||||
| header.inc.php
|
||||
| ========================================
|
||||
| Admin Header
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
if (!defined('CC_INI_SET')) die("Access Denied");
|
||||
|
||||
$langFolder = (defined('LANG_FOLDER') && constant('LANG_FOLDER')) ? LANG_FOLDER : $config['defaultLang'];
|
||||
include CC_ROOT_DIR.CC_DS.'language'.CC_DS.$langFolder.CC_DS.'config.php';
|
||||
|
||||
?>
|
||||
<!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>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $charsetIso; ?>" />
|
||||
<link href="<?php echo $GLOBALS['rootRel'].$glob['adminFolder']; ?>/styles/style.css" rel="stylesheet" type="text/css" />
|
||||
<script type="text/javascript" src="<?php echo $GLOBALS['rootRel']; ?>js/prototype.js"></script>
|
||||
<script type="text/javascript" src="<?php echo $GLOBALS['rootRel']; ?>js/scriptaculous.js"></script>
|
||||
<script type="text/javascript" src="<?php echo $GLOBALS['rootRel']; ?>js/jslibrary.js"></script>
|
||||
<?php
|
||||
if (isset($jsScript)) { ?>
|
||||
<script type="text/javascript">
|
||||
<?php echo $jsScript; ?>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<title>CubeCart™ - <?php echo $lang['admin_common']['incs_administration'];?></title>
|
||||
</head>
|
||||
<body id="pageTop">
|
||||
<?php
|
||||
if (isset($ccAdminData['adminId']) && $ccAdminData['adminId']>0) {
|
||||
?>
|
||||
<!-- start wrapping table -->
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td valign="top" width="180" rowspan="3" class="tdNav">
|
||||
<?php require(CC_ROOT_DIR . CC_DS . $glob['adminFolder'] . CC_DS . "includes" .CC_DS. "navigation.inc.php"); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" class="tdContent">
|
||||
<!-- end wrapping table -->
|
||||
<div id="topBar">
|
||||
<div id="loginBar">
|
||||
<span class="txtLogin"><?php echo $lang['admin_common']['incs_logged_in_as'];?> <strong><?php echo $ccAdminData['username']; ?></strong> [ </span><a href="<?php echo $GLOBALS['rootRel']; ?><?php echo $glob['adminFile']; ?>?_g=logout" class="txtLink"><?php echo $lang['admin_common']['incs_logout'];?></a> <span class="txtLogin">|</span> <a href="<?php echo $GLOBALS['rootRel']; ?><?php echo $glob['adminFile']; ?>?_g=adminusers/changePass" class="txtLink"><?php echo $lang['admin_common']['incs_change_pass'];?></a> <span class="txtLogin">]</span>
|
||||
</div>
|
||||
|
||||
<div id="dateBar">
|
||||
<span class="txtLogin"><?php echo formatTime(time(),$strftime); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- start of admin content -->
|
||||
<div id="contentPad">
|
||||
<?php } ?>
|
||||
3
_cubecart/CubeCart-4.3.0/admin/includes/index.php
Executable file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
die("Access Denied");
|
||||
?>
|
||||
128
_cubecart/CubeCart-4.3.0/admin/includes/navigation.inc.php
Executable file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/v4-software-license
|
||||
+--------------------------------------------------------------------------
|
||||
| navigation.inc.php
|
||||
| ========================================
|
||||
| Admin Navigation links
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
if(!defined('CC_INI_SET')){ die("Access Denied"); }
|
||||
|
||||
$link401 = "href=\"javascript:alert('".$lang['admin_common']['nav_permission_error']."');\" class=\"txtNullLink\"";
|
||||
?>
|
||||
<div id="adminNavigation" style="width: 180px;">
|
||||
|
||||
<div style="padding-left: 14px">
|
||||
<a href="http://www.cubecart.com" target="_blank">
|
||||
<img src="<?php echo $GLOBALS['rootRel'].$glob['adminFolder']; ?>/images/ccAdminLogo.gif" alt="" width="156" height="31" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div id="menuList" class="navMenu" style="padding-top: 10px;">
|
||||
|
||||
<span class="navTitle" onclick="Effect.toggle('navStoreLinks', 'blind');"><?php echo $lang['admin_common']['nav_navigation'];?></span>
|
||||
<ul id="navStoreLinks">
|
||||
<li><a href="<?php echo $GLOBALS['rootRel'].$glob['adminFile']; ?>" target="_self" class="txtLink"><?php echo $lang['admin_common']['nav_admin_home'];?></a></li>
|
||||
<li><a href="<?php echo $GLOBALS['rootRel']; ?>index.php" target="_blank" class="txtLink"><?php echo $lang['admin_common']['nav_store_home'];?></a></li>
|
||||
</ul>
|
||||
|
||||
<span class="navTitle" onclick="Effect.toggle('navStoreConfig', 'blind');"><?php echo $lang['admin_common']['nav_store_config'];?></span>
|
||||
<ul class="navItem" id="navStoreConfig">
|
||||
<li><a <?php if(permission("settings","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=settings/index" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_gen_settings'];?></a></li>
|
||||
<li><a <?php if(permission("settings","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=settings/tax" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_taxes'];?></a></li>
|
||||
<li><a <?php if(permission("settings","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=settings/geo" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_countries_zones'];?></a></li>
|
||||
<li><a <?php if(permission("settings","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=settings/currency" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_currencies'];?></a></li>
|
||||
<li><a <?php if(permission("settings","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=settings/logo" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_logo'];?></a></li>
|
||||
</ul>
|
||||
|
||||
<span class="navTitle" onclick="Effect.toggle('navStoreModules', 'blind');"><?php echo $lang['admin_common']['nav_modules'];?></span>
|
||||
<ul class="navItem" id="navStoreModules">
|
||||
<li><a <?php if(permission("shipping","read")==TRUE){ ?>href="<?php echo $glob['adminFile']; ?>?_g=modules&module=shipping" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_shipping'];?></a></li>
|
||||
<li><a <?php if(permission("gateways","read")==TRUE){ ?>href="<?php echo $glob['adminFile']; ?>?_g=modules&module=gateway" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_gateways'];?></a></li>
|
||||
<li><a <?php if(permission("gateways","read")==TRUE){ ?>href="<?php echo $glob['adminFile']; ?>?_g=modules&module=affiliate" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_affiliates'];?></a></li>
|
||||
<li><a <?php if(permission("gateways","read")==TRUE){ ?>href="<?php echo $glob['adminFile']; ?>?_g=modules&module=altCheckout" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_alt_checkout'];?></a></li>
|
||||
<li><a <?php if(permission("filemanager","edit")==TRUE){ ?>href="<?php echo $glob['adminFile']; ?>?_g=filemanager/language" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_edit_langs'];?></a></li>
|
||||
<li><a <?php if(permission("settings","write")==TRUE){ ?>href="<?php echo $glob['adminFile']; ?>?_g=modules&module=installer" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_module_installer']; ?></a></li>
|
||||
</ul>
|
||||
|
||||
<span class="navTitle" onclick="Effect.toggle('navStoreCatalog', 'blind');"><?php echo $lang['admin_common']['nav_catalog'];?></span>
|
||||
<ul class="navItem" id="navStoreCatalog">
|
||||
<li><a <?php if(permission("products","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=products/index" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_view_products'];?></a></li>
|
||||
<li><a <?php if(permission("products","write")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=products/index&mode=new" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_add_product'];?></a></li>
|
||||
<li><a <?php if(permission("products","write")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=products/options" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_product_options'];?></a></li>
|
||||
<li><a <?php if(permission("reviews","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=reviews/index" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_prod_reviews'];?></a></li>
|
||||
<li><a <?php if(permission("offers","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=products/coupons" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_coupons'];?></a></li>
|
||||
|
||||
<li><a <?php if(permission("products","write")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=products/giftCertificates" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_gift_certificates'];?></a></li>
|
||||
|
||||
<li><a <?php if(permission("categories","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=categories/index" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_view_categories'];?></a></li>
|
||||
<li><a <?php if(permission("categories","write")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=categories/index&mode=new" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_add_categories'];?></a></li>
|
||||
|
||||
<li><a <?php if(permission("products","write")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=products/import" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_import_cat'];?></a></li>
|
||||
<li><a <?php if(permission("products","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=products/export" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_export_cat'];?></a></li>
|
||||
</ul>
|
||||
|
||||
<span class="navTitle" onclick="Effect.toggle('navStoreCustomers', 'blind');"><?php echo $lang['admin_common']['nav_customers'];?></span>
|
||||
<ul class="navItem" id="navStoreCustomers">
|
||||
<li><a <?php if(permission("customers","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=customers/index" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_view_customers'];?></a></li>
|
||||
<li><a <?php if(permission("customers","write")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=customers/email" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_email_customers'];?></a></li>
|
||||
<li><a <?php if(permission("orders","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=orders/index" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_orders'];?></a></li>
|
||||
<li><a <?php if(permission("orders","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=orders/transLogs" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_transaction_logs'];?></a></li>
|
||||
</ul>
|
||||
|
||||
<span class="navTitle" onclick="Effect.toggle('navStoreFilemanager', 'blind');"><?php echo $lang['admin_common']['nav_file_manager'];?></span>
|
||||
<ul class="navItem" id="navStoreFilemanager">
|
||||
<li><a <?php if(permission("filemanager","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=filemanager/index" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_manage_images']?></a></li>
|
||||
<li><a <?php if(permission("filemanager","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=filemanager/index" onclick="openPopUp('<?php echo $GLOBALS['rootRel'].$glob['adminFolder']; ?>/includes/rte/editor/filemanager/browser/default/browser.html?Type=uploads&Connector=<?php echo urlencode($GLOBALS['rootRel'].$glob['adminFolder']); ?>%2Fincludes%2Frte%2Feditor%2Ffilemanager%2Fconnectors%2Fphp%2Fconnector.php','filemanager',700,600)" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_upload_images'];?></a></li>
|
||||
</ul>
|
||||
<span class="navTitle" onclick="Effect.toggle('navStoreStats', 'blind');"><?php echo $lang['admin_common']['nav_statistics'];?></span>
|
||||
<ul class="navItem" id="navStoreStats">
|
||||
<li><a <?php if(permission("statistics","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=stats/index" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_view_stats'];?></a></li>
|
||||
</ul>
|
||||
|
||||
<span class="navTitle" onclick="Effect.toggle('navStoreDocuments', 'blind');"><?php echo $lang['admin_common']['nav_documents'];?></span>
|
||||
<ul class="navItem" id="navStoreDocuments">
|
||||
<li><a <?php if(permission("documents","edit")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=docs/home" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_homepage'];?></a></li>
|
||||
<li><a <?php if(permission("documents","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=docs/siteDocs" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_site_docs'];?></a></li>
|
||||
</ul>
|
||||
|
||||
<span class="navTitle" onclick="Effect.toggle('navStoreMisc', 'blind');"><?php echo $lang['admin_common']['nav_misc'];?></span>
|
||||
<ul class="navItem" id="navStoreMisc">
|
||||
<li><a href="<?php echo $glob['adminFile']; ?>?_g=misc/serverInfo" class="txtLink"><?php echo $lang['admin_common']['nav_server_info'];?></a></li>
|
||||
</ul>
|
||||
|
||||
<span class="navTitle" onclick="Effect.toggle('navStoreUsers', 'blind');"><?php echo $lang['admin_common']['nav_admin_users'];?></span>
|
||||
<ul class="navItem" id="navStoreUsers">
|
||||
<li><a <?php if(permission("administrators","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=adminusers/administrators" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_administrators'];?></a></li>
|
||||
<li><a href="<?php echo $glob['adminFile']; ?>?_g=adminusers/sessions" class="txtLink"><?php echo $lang['admin_common']['nav_admin_sessions'];?></a></li>
|
||||
<li><a href="<?php echo $glob['adminFile']; ?>?_g=adminusers/logs" class="txtLink"><?php echo $lang['admin_common']['nav_admin_logs'];?></a></li>
|
||||
</ul>
|
||||
|
||||
<span class="navTitle" onclick="Effect.toggle('navStoreMaintenance', 'blind');"><?php echo $lang['admin_common']['nav_maintenance'];?></span>
|
||||
<ul class="navItem" id="navStoreMaintenance">
|
||||
<li><a <?php if(permission("maintenance","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=maintenance/database" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_database'];?></a></li>
|
||||
<li><a <?php if(permission("maintenance","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=maintenance/backup" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_backup'];?></a></li>
|
||||
<li><a <?php if(permission("maintenance","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=maintenance/thumbnails" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_thumbnails'];?></a></li>
|
||||
<li><a <?php if(permission("maintenance","read")==true){ ?>href="<?php echo $glob['adminFile']; ?>?_g=maintenance/rebuild" class="txtLink"<?php } else { echo $link401; } ?>><?php echo $lang['admin_common']['nav_rebuild'];?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKContextMenu Class: renders an control a context menu.
|
||||
*/
|
||||
|
||||
var FCKContextMenu = function( parentWindow, langDir )
|
||||
{
|
||||
this.CtrlDisable = false ;
|
||||
|
||||
var oPanel = this._Panel = new FCKPanel( parentWindow ) ;
|
||||
oPanel.AppendStyleSheet( FCKConfig.SkinEditorCSS ) ;
|
||||
oPanel.IsContextMenu = true ;
|
||||
|
||||
// The FCKTools.DisableSelection doesn't seems to work to avoid dragging of the icons in Mozilla
|
||||
// so we stop the start of the dragging
|
||||
if ( FCKBrowserInfo.IsGecko )
|
||||
oPanel.Document.addEventListener( 'draggesture', function(e) {e.preventDefault(); return false;}, true ) ;
|
||||
|
||||
var oMenuBlock = this._MenuBlock = new FCKMenuBlock() ;
|
||||
oMenuBlock.Panel = oPanel ;
|
||||
oMenuBlock.OnClick = FCKTools.CreateEventListener( FCKContextMenu_MenuBlock_OnClick, this ) ;
|
||||
|
||||
this._Redraw = true ;
|
||||
}
|
||||
|
||||
|
||||
FCKContextMenu.prototype.SetMouseClickWindow = function( mouseClickWindow )
|
||||
{
|
||||
if ( !FCKBrowserInfo.IsIE )
|
||||
{
|
||||
this._Document = mouseClickWindow.document ;
|
||||
if ( FCKBrowserInfo.IsOpera && !( 'oncontextmenu' in document.createElement('foo') ) )
|
||||
{
|
||||
this._Document.addEventListener( 'mousedown', FCKContextMenu_Document_OnMouseDown, false ) ;
|
||||
this._Document.addEventListener( 'mouseup', FCKContextMenu_Document_OnMouseUp, false ) ;
|
||||
}
|
||||
this._Document.addEventListener( 'contextmenu', FCKContextMenu_Document_OnContextMenu, false ) ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The customData parameter is just a value that will be send to the command that is executed,
|
||||
so it's possible to reuse the same command for several items just by assigning different data for each one.
|
||||
*/
|
||||
FCKContextMenu.prototype.AddItem = function( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled, customData )
|
||||
{
|
||||
var oItem = this._MenuBlock.AddItem( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled, customData ) ;
|
||||
this._Redraw = true ;
|
||||
return oItem ;
|
||||
}
|
||||
|
||||
FCKContextMenu.prototype.AddSeparator = function()
|
||||
{
|
||||
this._MenuBlock.AddSeparator() ;
|
||||
this._Redraw = true ;
|
||||
}
|
||||
|
||||
FCKContextMenu.prototype.RemoveAllItems = function()
|
||||
{
|
||||
this._MenuBlock.RemoveAllItems() ;
|
||||
this._Redraw = true ;
|
||||
}
|
||||
|
||||
FCKContextMenu.prototype.AttachToElement = function( element )
|
||||
{
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
FCKTools.AddEventListenerEx( element, 'contextmenu', FCKContextMenu_AttachedElement_OnContextMenu, this ) ;
|
||||
else
|
||||
element._FCKContextMenu = this ;
|
||||
}
|
||||
|
||||
function FCKContextMenu_Document_OnContextMenu( e )
|
||||
{
|
||||
if ( FCKConfig.BrowserContextMenu )
|
||||
return true ;
|
||||
|
||||
var el = e.target ;
|
||||
|
||||
while ( el )
|
||||
{
|
||||
if ( el._FCKContextMenu )
|
||||
{
|
||||
if ( el._FCKContextMenu.CtrlDisable && ( e.ctrlKey || e.metaKey ) )
|
||||
return true ;
|
||||
|
||||
FCKTools.CancelEvent( e ) ;
|
||||
FCKContextMenu_AttachedElement_OnContextMenu( e, el._FCKContextMenu, el ) ;
|
||||
return false ;
|
||||
}
|
||||
el = el.parentNode ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
var FCKContextMenu_OverrideButton ;
|
||||
|
||||
function FCKContextMenu_Document_OnMouseDown( e )
|
||||
{
|
||||
if( !e || e.button != 2 )
|
||||
return false ;
|
||||
|
||||
if ( FCKConfig.BrowserContextMenu )
|
||||
return true ;
|
||||
|
||||
var el = e.target ;
|
||||
|
||||
while ( el )
|
||||
{
|
||||
if ( el._FCKContextMenu )
|
||||
{
|
||||
if ( el._FCKContextMenu.CtrlDisable && ( e.ctrlKey || e.metaKey ) )
|
||||
return true ;
|
||||
|
||||
var overrideButton = FCKContextMenu_OverrideButton ;
|
||||
if( !overrideButton )
|
||||
{
|
||||
var doc = FCKTools.GetElementDocument( e.target ) ;
|
||||
overrideButton = FCKContextMenu_OverrideButton = doc.createElement('input') ;
|
||||
overrideButton.type = 'button' ;
|
||||
var buttonHolder = doc.createElement('p') ;
|
||||
doc.body.appendChild( buttonHolder ) ;
|
||||
buttonHolder.appendChild( overrideButton ) ;
|
||||
}
|
||||
|
||||
overrideButton.style.cssText = 'position:absolute;top:' + ( e.clientY - 2 ) +
|
||||
'px;left:' + ( e.clientX - 2 ) +
|
||||
'px;width:5px;height:5px;opacity:0.01' ;
|
||||
}
|
||||
el = el.parentNode ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
function FCKContextMenu_Document_OnMouseUp( e )
|
||||
{
|
||||
if ( FCKConfig.BrowserContextMenu )
|
||||
return true ;
|
||||
|
||||
var overrideButton = FCKContextMenu_OverrideButton ;
|
||||
|
||||
if ( overrideButton )
|
||||
{
|
||||
var parent = overrideButton.parentNode ;
|
||||
parent.parentNode.removeChild( parent ) ;
|
||||
FCKContextMenu_OverrideButton = undefined ;
|
||||
|
||||
if( e && e.button == 2 )
|
||||
{
|
||||
FCKContextMenu_Document_OnContextMenu( e ) ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
function FCKContextMenu_AttachedElement_OnContextMenu( ev, fckContextMenu, el )
|
||||
{
|
||||
if ( ( fckContextMenu.CtrlDisable && ( ev.ctrlKey || ev.metaKey ) ) || FCKConfig.BrowserContextMenu )
|
||||
return true ;
|
||||
|
||||
var eTarget = el || this ;
|
||||
|
||||
if ( fckContextMenu.OnBeforeOpen )
|
||||
fckContextMenu.OnBeforeOpen.call( fckContextMenu, eTarget ) ;
|
||||
|
||||
if ( fckContextMenu._MenuBlock.Count() == 0 )
|
||||
return false ;
|
||||
|
||||
if ( fckContextMenu._Redraw )
|
||||
{
|
||||
fckContextMenu._MenuBlock.Create( fckContextMenu._Panel.MainNode ) ;
|
||||
fckContextMenu._Redraw = false ;
|
||||
}
|
||||
|
||||
// This will avoid that the content of the context menu can be dragged in IE
|
||||
// as the content of the panel is recreated we need to do it every time
|
||||
FCKTools.DisableSelection( fckContextMenu._Panel.Document.body ) ;
|
||||
|
||||
var x = 0 ;
|
||||
var y = 0 ;
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
{
|
||||
x = ev.screenX ;
|
||||
y = ev.screenY ;
|
||||
}
|
||||
else if ( FCKBrowserInfo.IsSafari )
|
||||
{
|
||||
x = ev.clientX ;
|
||||
y = ev.clientY ;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = ev.pageX ;
|
||||
y = ev.pageY ;
|
||||
}
|
||||
fckContextMenu._Panel.Show( x, y, ev.currentTarget || null ) ;
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
function FCKContextMenu_MenuBlock_OnClick( menuItem, contextMenu )
|
||||
{
|
||||
contextMenu._Panel.Hide() ;
|
||||
FCKTools.RunFunction( contextMenu.OnItemClick, contextMenu, menuItem ) ;
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* The Data Processor is responsible for transforming the input and output data
|
||||
* in the editor. For more info:
|
||||
* http://dev.fckeditor.net/wiki/Components/DataProcessor
|
||||
*
|
||||
* The default implementation offers the base XHTML compatibility features of
|
||||
* FCKeditor. Further Data Processors may be implemented for other purposes.
|
||||
*
|
||||
*/
|
||||
|
||||
var FCKDataProcessor = function()
|
||||
{}
|
||||
|
||||
FCKDataProcessor.prototype =
|
||||
{
|
||||
/*
|
||||
* Returns a string representing the HTML format of "data". The returned
|
||||
* value will be loaded in the editor.
|
||||
* The HTML must be from <html> to </html>, including <head>, <body> and
|
||||
* eventually the DOCTYPE.
|
||||
* Note: HTML comments may already be part of the data because of the
|
||||
* pre-processing made with ProtectedSource.
|
||||
* @param {String} data The data to be converted in the
|
||||
* DataProcessor specific format.
|
||||
*/
|
||||
ConvertToHtml : function( data )
|
||||
{
|
||||
// The default data processor must handle two different cases depending
|
||||
// on the FullPage setting. Custom Data Processors will not be
|
||||
// compatible with FullPage, much probably.
|
||||
if ( FCKConfig.FullPage )
|
||||
{
|
||||
// Save the DOCTYPE.
|
||||
FCK.DocTypeDeclaration = data.match( FCKRegexLib.DocTypeTag ) ;
|
||||
|
||||
// Check if the <body> tag is available.
|
||||
if ( !FCKRegexLib.HasBodyTag.test( data ) )
|
||||
data = '<body>' + data + '</body>' ;
|
||||
|
||||
// Check if the <html> tag is available.
|
||||
if ( !FCKRegexLib.HtmlOpener.test( data ) )
|
||||
data = '<html dir="' + FCKConfig.ContentLangDirection + '">' + data + '</html>' ;
|
||||
|
||||
// Check if the <head> tag is available.
|
||||
if ( !FCKRegexLib.HeadOpener.test( data ) )
|
||||
data = data.replace( FCKRegexLib.HtmlOpener, '$&<head><title></title></head>' ) ;
|
||||
|
||||
return data ;
|
||||
}
|
||||
else
|
||||
{
|
||||
var html =
|
||||
FCKConfig.DocType +
|
||||
'<html dir="' + FCKConfig.ContentLangDirection + '"' ;
|
||||
|
||||
// On IE, if you are using a DOCTYPE different of HTML 4 (like
|
||||
// XHTML), you must force the vertical scroll to show, otherwise
|
||||
// the horizontal one may appear when the page needs vertical scrolling.
|
||||
// TODO : Check it with IE7 and make it IE6- if it is the case.
|
||||
if ( FCKBrowserInfo.IsIE && FCKConfig.DocType.length > 0 && !FCKRegexLib.Html4DocType.test( FCKConfig.DocType ) )
|
||||
html += ' style="overflow-y: scroll"' ;
|
||||
|
||||
html += '><head><title></title></head>' +
|
||||
'<body' + FCKConfig.GetBodyAttributes() + '>' +
|
||||
data +
|
||||
'</body></html>' ;
|
||||
|
||||
return html ;
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Converts a DOM (sub-)tree to a string in the data format.
|
||||
* @param {Object} rootNode The node that contains the DOM tree to be
|
||||
* converted to the data format.
|
||||
* @param {Boolean} excludeRoot Indicates that the root node must not
|
||||
* be included in the conversion, only its children.
|
||||
* @param {Boolean} format Indicates that the data must be formatted
|
||||
* for human reading. Not all Data Processors may provide it.
|
||||
*/
|
||||
ConvertToDataFormat : function( rootNode, excludeRoot, ignoreIfEmptyParagraph, format )
|
||||
{
|
||||
var data = FCKXHtml.GetXHTML( rootNode, !excludeRoot, format ) ;
|
||||
|
||||
if ( ignoreIfEmptyParagraph && FCKRegexLib.EmptyOutParagraph.test( data ) )
|
||||
return '' ;
|
||||
|
||||
return data ;
|
||||
},
|
||||
|
||||
/*
|
||||
* Makes any necessary changes to a piece of HTML for insertion in the
|
||||
* editor selection position.
|
||||
* @param {String} html The HTML to be fixed.
|
||||
*/
|
||||
FixHtml : function( html )
|
||||
{
|
||||
return html ;
|
||||
}
|
||||
} ;
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* This is a generic Document Fragment object. It is not intended to provide
|
||||
* the W3C implementation, but is a way to fix the missing of a real Document
|
||||
* Fragment in IE (where document.createDocumentFragment() returns a normal
|
||||
* document instead), giving a standard interface for it.
|
||||
* (IE Implementation)
|
||||
*/
|
||||
|
||||
var FCKDocumentFragment = function( parentDocument, baseDocFrag )
|
||||
{
|
||||
this.RootNode = baseDocFrag || parentDocument.createDocumentFragment() ;
|
||||
}
|
||||
|
||||
FCKDocumentFragment.prototype =
|
||||
{
|
||||
|
||||
// Append the contents of this Document Fragment to another element.
|
||||
AppendTo : function( targetNode )
|
||||
{
|
||||
targetNode.appendChild( this.RootNode ) ;
|
||||
},
|
||||
|
||||
AppendHtml : function( html )
|
||||
{
|
||||
var eTmpDiv = this.RootNode.ownerDocument.createElement( 'div' ) ;
|
||||
eTmpDiv.innerHTML = html ;
|
||||
FCKDomTools.MoveChildren( eTmpDiv, this.RootNode ) ;
|
||||
},
|
||||
|
||||
InsertAfterNode : function( existingNode )
|
||||
{
|
||||
FCKDomTools.InsertAfterNode( existingNode, this.RootNode ) ;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* This is a generic Document Fragment object. It is not intended to provide
|
||||
* the W3C implementation, but is a way to fix the missing of a real Document
|
||||
* Fragment in IE (where document.createDocumentFragment() returns a normal
|
||||
* document instead), giving a standard interface for it.
|
||||
* (IE Implementation)
|
||||
*/
|
||||
|
||||
var FCKDocumentFragment = function( parentDocument )
|
||||
{
|
||||
this._Document = parentDocument ;
|
||||
this.RootNode = parentDocument.createElement( 'div' ) ;
|
||||
}
|
||||
|
||||
// Append the contents of this Document Fragment to another node.
|
||||
FCKDocumentFragment.prototype =
|
||||
{
|
||||
|
||||
AppendTo : function( targetNode )
|
||||
{
|
||||
FCKDomTools.MoveChildren( this.RootNode, targetNode ) ;
|
||||
},
|
||||
|
||||
AppendHtml : function( html )
|
||||
{
|
||||
var eTmpDiv = this._Document.createElement( 'div' ) ;
|
||||
eTmpDiv.innerHTML = html ;
|
||||
FCKDomTools.MoveChildren( eTmpDiv, this.RootNode ) ;
|
||||
},
|
||||
|
||||
InsertAfterNode : function( existingNode )
|
||||
{
|
||||
var eRoot = this.RootNode ;
|
||||
var eLast ;
|
||||
|
||||
while( ( eLast = eRoot.lastChild ) )
|
||||
FCKDomTools.InsertAfterNode( existingNode, eRoot.removeChild( eLast ) ) ;
|
||||
}
|
||||
} ;
|
||||
@@ -0,0 +1,935 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Class for working with a selection range, much like the W3C DOM Range, but
|
||||
* it is not intended to be an implementation of the W3C interface.
|
||||
*/
|
||||
|
||||
var FCKDomRange = function( sourceWindow )
|
||||
{
|
||||
this.Window = sourceWindow ;
|
||||
this._Cache = {} ;
|
||||
}
|
||||
|
||||
FCKDomRange.prototype =
|
||||
{
|
||||
|
||||
_UpdateElementInfo : function()
|
||||
{
|
||||
var innerRange = this._Range ;
|
||||
|
||||
if ( !innerRange )
|
||||
this.Release( true ) ;
|
||||
else
|
||||
{
|
||||
// For text nodes, the node itself is the StartNode.
|
||||
var eStart = innerRange.startContainer ;
|
||||
|
||||
var oElementPath = new FCKElementPath( eStart ) ;
|
||||
this.StartNode = eStart.nodeType == 3 ? eStart : eStart.childNodes[ innerRange.startOffset ] ;
|
||||
this.StartContainer = eStart ;
|
||||
this.StartBlock = oElementPath.Block ;
|
||||
this.StartBlockLimit = oElementPath.BlockLimit ;
|
||||
|
||||
if ( innerRange.collapsed )
|
||||
{
|
||||
this.EndNode = this.StartNode ;
|
||||
this.EndContainer = this.StartContainer ;
|
||||
this.EndBlock = this.StartBlock ;
|
||||
this.EndBlockLimit = this.StartBlockLimit ;
|
||||
}
|
||||
else
|
||||
{
|
||||
var eEnd = innerRange.endContainer ;
|
||||
|
||||
if ( eStart != eEnd )
|
||||
oElementPath = new FCKElementPath( eEnd ) ;
|
||||
|
||||
// The innerRange.endContainer[ innerRange.endOffset ] is not
|
||||
// usually part of the range, but the marker for the range end. So,
|
||||
// let's get the previous available node as the real end.
|
||||
var eEndNode = eEnd ;
|
||||
if ( innerRange.endOffset == 0 )
|
||||
{
|
||||
while ( eEndNode && !eEndNode.previousSibling )
|
||||
eEndNode = eEndNode.parentNode ;
|
||||
|
||||
if ( eEndNode )
|
||||
eEndNode = eEndNode.previousSibling ;
|
||||
}
|
||||
else if ( eEndNode.nodeType == 1 )
|
||||
eEndNode = eEndNode.childNodes[ innerRange.endOffset - 1 ] ;
|
||||
|
||||
this.EndNode = eEndNode ;
|
||||
this.EndContainer = eEnd ;
|
||||
this.EndBlock = oElementPath.Block ;
|
||||
this.EndBlockLimit = oElementPath.BlockLimit ;
|
||||
}
|
||||
}
|
||||
|
||||
this._Cache = {} ;
|
||||
},
|
||||
|
||||
CreateRange : function()
|
||||
{
|
||||
return new FCKW3CRange( this.Window.document ) ;
|
||||
},
|
||||
|
||||
DeleteContents : function()
|
||||
{
|
||||
if ( this._Range )
|
||||
{
|
||||
this._Range.deleteContents() ;
|
||||
this._UpdateElementInfo() ;
|
||||
}
|
||||
},
|
||||
|
||||
ExtractContents : function()
|
||||
{
|
||||
if ( this._Range )
|
||||
{
|
||||
var docFrag = this._Range.extractContents() ;
|
||||
this._UpdateElementInfo() ;
|
||||
return docFrag ;
|
||||
}
|
||||
return null ;
|
||||
},
|
||||
|
||||
CheckIsCollapsed : function()
|
||||
{
|
||||
if ( this._Range )
|
||||
return this._Range.collapsed ;
|
||||
|
||||
return false ;
|
||||
},
|
||||
|
||||
Collapse : function( toStart )
|
||||
{
|
||||
if ( this._Range )
|
||||
this._Range.collapse( toStart ) ;
|
||||
|
||||
this._UpdateElementInfo() ;
|
||||
},
|
||||
|
||||
Clone : function()
|
||||
{
|
||||
var oClone = FCKTools.CloneObject( this ) ;
|
||||
|
||||
if ( this._Range )
|
||||
oClone._Range = this._Range.cloneRange() ;
|
||||
|
||||
return oClone ;
|
||||
},
|
||||
|
||||
MoveToNodeContents : function( targetNode )
|
||||
{
|
||||
if ( !this._Range )
|
||||
this._Range = this.CreateRange() ;
|
||||
|
||||
this._Range.selectNodeContents( targetNode ) ;
|
||||
|
||||
this._UpdateElementInfo() ;
|
||||
},
|
||||
|
||||
MoveToElementStart : function( targetElement )
|
||||
{
|
||||
this.SetStart(targetElement,1) ;
|
||||
this.SetEnd(targetElement,1) ;
|
||||
},
|
||||
|
||||
// Moves to the first editing point inside a element. For example, in a
|
||||
// element tree like "<p><b><i></i></b> Text</p>", the start editing point
|
||||
// is "<p><b><i>^</i></b> Text</p>" (inside <i>).
|
||||
MoveToElementEditStart : function( targetElement )
|
||||
{
|
||||
var editableElement ;
|
||||
|
||||
while ( targetElement && targetElement.nodeType == 1 )
|
||||
{
|
||||
if ( FCKDomTools.CheckIsEditable( targetElement ) )
|
||||
editableElement = targetElement ;
|
||||
else if ( editableElement )
|
||||
break ; // If we already found an editable element, stop the loop.
|
||||
|
||||
targetElement = targetElement.firstChild ;
|
||||
}
|
||||
|
||||
if ( editableElement )
|
||||
this.MoveToElementStart( editableElement ) ;
|
||||
},
|
||||
|
||||
InsertNode : function( node )
|
||||
{
|
||||
if ( this._Range )
|
||||
this._Range.insertNode( node ) ;
|
||||
},
|
||||
|
||||
CheckIsEmpty : function()
|
||||
{
|
||||
if ( this.CheckIsCollapsed() )
|
||||
return true ;
|
||||
|
||||
// Inserts the contents of the range in a div tag.
|
||||
var eToolDiv = this.Window.document.createElement( 'div' ) ;
|
||||
this._Range.cloneContents().AppendTo( eToolDiv ) ;
|
||||
|
||||
FCKDomTools.TrimNode( eToolDiv ) ;
|
||||
|
||||
return ( eToolDiv.innerHTML.length == 0 ) ;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the start boundary of the current range is "visually" (like a
|
||||
* selection caret) at the beginning of the block. It means that some
|
||||
* things could be brefore the range, like spaces or empty inline elements,
|
||||
* but it would still be considered at the beginning of the block.
|
||||
*/
|
||||
CheckStartOfBlock : function()
|
||||
{
|
||||
var cache = this._Cache ;
|
||||
var bIsStartOfBlock = cache.IsStartOfBlock ;
|
||||
|
||||
if ( bIsStartOfBlock != undefined )
|
||||
return bIsStartOfBlock ;
|
||||
|
||||
// Take the block reference.
|
||||
var block = this.StartBlock || this.StartBlockLimit ;
|
||||
|
||||
var container = this._Range.startContainer ;
|
||||
var offset = this._Range.startOffset ;
|
||||
var currentNode ;
|
||||
|
||||
if ( offset > 0 )
|
||||
{
|
||||
// First, check the start container. If it is a text node, get the
|
||||
// substring of the node value before the range offset.
|
||||
if ( container.nodeType == 3 )
|
||||
{
|
||||
var textValue = container.nodeValue.substr( 0, offset ).Trim() ;
|
||||
|
||||
// If we have some text left in the container, we are not at
|
||||
// the end for the block.
|
||||
if ( textValue.length != 0 )
|
||||
return cache.IsStartOfBlock = false ;
|
||||
}
|
||||
else
|
||||
currentNode = container.childNodes[ offset - 1 ] ;
|
||||
}
|
||||
|
||||
// We'll not have a currentNode if the container was a text node, or
|
||||
// the offset is zero.
|
||||
if ( !currentNode )
|
||||
currentNode = FCKDomTools.GetPreviousSourceNode( container, true, null, block ) ;
|
||||
|
||||
while ( currentNode )
|
||||
{
|
||||
switch ( currentNode.nodeType )
|
||||
{
|
||||
case 1 :
|
||||
// It's not an inline element.
|
||||
if ( !FCKListsLib.InlineChildReqElements[ currentNode.nodeName.toLowerCase() ] )
|
||||
return cache.IsStartOfBlock = false ;
|
||||
|
||||
break ;
|
||||
|
||||
case 3 :
|
||||
// It's a text node with real text.
|
||||
if ( currentNode.nodeValue.Trim().length > 0 )
|
||||
return cache.IsStartOfBlock = false ;
|
||||
}
|
||||
|
||||
currentNode = FCKDomTools.GetPreviousSourceNode( currentNode, false, null, block ) ;
|
||||
}
|
||||
|
||||
return cache.IsStartOfBlock = true ;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the end boundary of the current range is "visually" (like a
|
||||
* selection caret) at the end of the block. It means that some things
|
||||
* could be after the range, like spaces, empty inline elements, or a
|
||||
* single <br>, but it would still be considered at the end of the block.
|
||||
*/
|
||||
CheckEndOfBlock : function( refreshSelection )
|
||||
{
|
||||
var isEndOfBlock = this._Cache.IsEndOfBlock ;
|
||||
|
||||
if ( isEndOfBlock != undefined )
|
||||
return isEndOfBlock ;
|
||||
|
||||
// Take the block reference.
|
||||
var block = this.EndBlock || this.EndBlockLimit ;
|
||||
|
||||
var container = this._Range.endContainer ;
|
||||
var offset = this._Range.endOffset ;
|
||||
var currentNode ;
|
||||
|
||||
// First, check the end container. If it is a text node, get the
|
||||
// substring of the node value after the range offset.
|
||||
if ( container.nodeType == 3 )
|
||||
{
|
||||
var textValue = container.nodeValue ;
|
||||
if ( offset < textValue.length )
|
||||
{
|
||||
textValue = textValue.substr( offset ) ;
|
||||
|
||||
// If we have some text left in the container, we are not at
|
||||
// the end for the block.
|
||||
if ( textValue.Trim().length != 0 )
|
||||
return this._Cache.IsEndOfBlock = false ;
|
||||
}
|
||||
}
|
||||
else
|
||||
currentNode = container.childNodes[ offset ] ;
|
||||
|
||||
// We'll not have a currentNode if the container was a text node, of
|
||||
// the offset is out the container children limits (after it probably).
|
||||
if ( !currentNode )
|
||||
currentNode = FCKDomTools.GetNextSourceNode( container, true, null, block ) ;
|
||||
|
||||
var hadBr = false ;
|
||||
|
||||
while ( currentNode )
|
||||
{
|
||||
switch ( currentNode.nodeType )
|
||||
{
|
||||
case 1 :
|
||||
var nodeName = currentNode.nodeName.toLowerCase() ;
|
||||
|
||||
// It's an inline element.
|
||||
if ( FCKListsLib.InlineChildReqElements[ nodeName ] )
|
||||
break ;
|
||||
|
||||
// It is the first <br> found.
|
||||
if ( nodeName == 'br' && !hadBr )
|
||||
{
|
||||
hadBr = true ;
|
||||
break ;
|
||||
}
|
||||
|
||||
return this._Cache.IsEndOfBlock = false ;
|
||||
|
||||
case 3 :
|
||||
// It's a text node with real text.
|
||||
if ( currentNode.nodeValue.Trim().length > 0 )
|
||||
return this._Cache.IsEndOfBlock = false ;
|
||||
}
|
||||
|
||||
currentNode = FCKDomTools.GetNextSourceNode( currentNode, false, null, block ) ;
|
||||
}
|
||||
|
||||
if ( refreshSelection )
|
||||
this.Select() ;
|
||||
|
||||
return this._Cache.IsEndOfBlock = true ;
|
||||
},
|
||||
|
||||
// This is an "intrusive" way to create a bookmark. It includes <span> tags
|
||||
// in the range boundaries. The advantage of it is that it is possible to
|
||||
// handle DOM mutations when moving back to the bookmark.
|
||||
// Attention: the inclusion of nodes in the DOM is a design choice and
|
||||
// should not be changed as there are other points in the code that may be
|
||||
// using those nodes to perform operations. See GetBookmarkNode.
|
||||
// For performance, includeNodes=true if intended to SelectBookmark.
|
||||
CreateBookmark : function( includeNodes )
|
||||
{
|
||||
// Create the bookmark info (random IDs).
|
||||
var oBookmark =
|
||||
{
|
||||
StartId : (new Date()).valueOf() + Math.floor(Math.random()*1000) + 'S',
|
||||
EndId : (new Date()).valueOf() + Math.floor(Math.random()*1000) + 'E'
|
||||
} ;
|
||||
|
||||
var oDoc = this.Window.document ;
|
||||
var eStartSpan ;
|
||||
var eEndSpan ;
|
||||
var oClone ;
|
||||
|
||||
// For collapsed ranges, add just the start marker.
|
||||
if ( !this.CheckIsCollapsed() )
|
||||
{
|
||||
eEndSpan = oDoc.createElement( 'span' ) ;
|
||||
eEndSpan.style.display = 'none' ;
|
||||
eEndSpan.id = oBookmark.EndId ;
|
||||
eEndSpan.setAttribute( '_fck_bookmark', true ) ;
|
||||
|
||||
// For IE, it must have something inside, otherwise it may be
|
||||
// removed during DOM operations.
|
||||
// if ( FCKBrowserInfo.IsIE )
|
||||
eEndSpan.innerHTML = ' ' ;
|
||||
|
||||
oClone = this.Clone() ;
|
||||
oClone.Collapse( false ) ;
|
||||
oClone.InsertNode( eEndSpan ) ;
|
||||
}
|
||||
|
||||
eStartSpan = oDoc.createElement( 'span' ) ;
|
||||
eStartSpan.style.display = 'none' ;
|
||||
eStartSpan.id = oBookmark.StartId ;
|
||||
eStartSpan.setAttribute( '_fck_bookmark', true ) ;
|
||||
|
||||
// For IE, it must have something inside, otherwise it may be removed
|
||||
// during DOM operations.
|
||||
// if ( FCKBrowserInfo.IsIE )
|
||||
eStartSpan.innerHTML = ' ' ;
|
||||
|
||||
oClone = this.Clone() ;
|
||||
oClone.Collapse( true ) ;
|
||||
oClone.InsertNode( eStartSpan ) ;
|
||||
|
||||
if ( includeNodes )
|
||||
{
|
||||
oBookmark.StartNode = eStartSpan ;
|
||||
oBookmark.EndNode = eEndSpan ;
|
||||
}
|
||||
|
||||
// Update the range position.
|
||||
if ( eEndSpan )
|
||||
{
|
||||
this.SetStart( eStartSpan, 4 ) ;
|
||||
this.SetEnd( eEndSpan, 3 ) ;
|
||||
}
|
||||
else
|
||||
this.MoveToPosition( eStartSpan, 4 ) ;
|
||||
|
||||
return oBookmark ;
|
||||
},
|
||||
|
||||
// This one should be a part of a hypothetic "bookmark" object.
|
||||
GetBookmarkNode : function( bookmark, start )
|
||||
{
|
||||
var doc = this.Window.document ;
|
||||
|
||||
if ( start )
|
||||
return bookmark.StartNode || doc.getElementById( bookmark.StartId ) ;
|
||||
else
|
||||
return bookmark.EndNode || doc.getElementById( bookmark.EndId ) ;
|
||||
},
|
||||
|
||||
MoveToBookmark : function( bookmark, preserveBookmark )
|
||||
{
|
||||
var eStartSpan = this.GetBookmarkNode( bookmark, true ) ;
|
||||
var eEndSpan = this.GetBookmarkNode( bookmark, false ) ;
|
||||
|
||||
this.SetStart( eStartSpan, 3 ) ;
|
||||
|
||||
if ( !preserveBookmark )
|
||||
FCKDomTools.RemoveNode( eStartSpan ) ;
|
||||
|
||||
// If collapsed, the end span will not be available.
|
||||
if ( eEndSpan )
|
||||
{
|
||||
this.SetEnd( eEndSpan, 3 ) ;
|
||||
|
||||
if ( !preserveBookmark )
|
||||
FCKDomTools.RemoveNode( eEndSpan ) ;
|
||||
}
|
||||
else
|
||||
this.Collapse( true ) ;
|
||||
|
||||
this._UpdateElementInfo() ;
|
||||
},
|
||||
|
||||
// Non-intrusive bookmark algorithm
|
||||
CreateBookmark2 : function()
|
||||
{
|
||||
// If there is no range then get out of here.
|
||||
// It happens on initial load in Safari #962 and if the editor it's hidden also in Firefox
|
||||
if ( ! this._Range )
|
||||
return { "Start" : 0, "End" : 0 } ;
|
||||
|
||||
// First, we record down the offset values
|
||||
var bookmark =
|
||||
{
|
||||
"Start" : [ this._Range.startOffset ],
|
||||
"End" : [ this._Range.endOffset ]
|
||||
} ;
|
||||
// Since we're treating the document tree as normalized, we need to backtrack the text lengths
|
||||
// of previous text nodes into the offset value.
|
||||
var curStart = this._Range.startContainer.previousSibling ;
|
||||
var curEnd = this._Range.endContainer.previousSibling ;
|
||||
|
||||
// Also note that the node that we use for "address base" would change during backtracking.
|
||||
var addrStart = this._Range.startContainer ;
|
||||
var addrEnd = this._Range.endContainer ;
|
||||
while ( curStart && addrStart.nodeType == 3 )
|
||||
{
|
||||
bookmark.Start[0] += curStart.length ;
|
||||
addrStart = curStart ;
|
||||
curStart = curStart.previousSibling ;
|
||||
}
|
||||
while ( curEnd && addrEnd.nodeType == 3 )
|
||||
{
|
||||
bookmark.End[0] += curEnd.length ;
|
||||
addrEnd = curEnd ;
|
||||
curEnd = curEnd.previousSibling ;
|
||||
}
|
||||
|
||||
// If the object pointed to by the startOffset and endOffset are text nodes, we need
|
||||
// to backtrack and add in the text offset to the bookmark addresses.
|
||||
if ( addrStart.nodeType == 1 && addrStart.childNodes[bookmark.Start[0]] && addrStart.childNodes[bookmark.Start[0]].nodeType == 3 )
|
||||
{
|
||||
var curNode = addrStart.childNodes[bookmark.Start[0]] ;
|
||||
var offset = 0 ;
|
||||
while ( curNode.previousSibling && curNode.previousSibling.nodeType == 3 )
|
||||
{
|
||||
curNode = curNode.previousSibling ;
|
||||
offset += curNode.length ;
|
||||
}
|
||||
addrStart = curNode ;
|
||||
bookmark.Start[0] = offset ;
|
||||
}
|
||||
if ( addrEnd.nodeType == 1 && addrEnd.childNodes[bookmark.End[0]] && addrEnd.childNodes[bookmark.End[0]].nodeType == 3 )
|
||||
{
|
||||
var curNode = addrEnd.childNodes[bookmark.End[0]] ;
|
||||
var offset = 0 ;
|
||||
while ( curNode.previousSibling && curNode.previousSibling.nodeType == 3 )
|
||||
{
|
||||
curNode = curNode.previousSibling ;
|
||||
offset += curNode.length ;
|
||||
}
|
||||
addrEnd = curNode ;
|
||||
bookmark.End[0] = offset ;
|
||||
}
|
||||
|
||||
// Then, we record down the precise position of the container nodes
|
||||
// by walking up the DOM tree and counting their childNode index
|
||||
bookmark.Start = FCKDomTools.GetNodeAddress( addrStart, true ).concat( bookmark.Start ) ;
|
||||
bookmark.End = FCKDomTools.GetNodeAddress( addrEnd, true ).concat( bookmark.End ) ;
|
||||
return bookmark;
|
||||
},
|
||||
|
||||
MoveToBookmark2 : function( bookmark )
|
||||
{
|
||||
// Reverse the childNode counting algorithm in CreateBookmark2()
|
||||
var curStart = FCKDomTools.GetNodeFromAddress( this.Window.document, bookmark.Start.slice( 0, -1 ), true ) ;
|
||||
var curEnd = FCKDomTools.GetNodeFromAddress( this.Window.document, bookmark.End.slice( 0, -1 ), true ) ;
|
||||
|
||||
// Generate the W3C Range object and update relevant data
|
||||
this.Release( true ) ;
|
||||
this._Range = new FCKW3CRange( this.Window.document ) ;
|
||||
var startOffset = bookmark.Start[ bookmark.Start.length - 1 ] ;
|
||||
var endOffset = bookmark.End[ bookmark.End.length - 1 ] ;
|
||||
while ( curStart.nodeType == 3 && startOffset > curStart.length )
|
||||
{
|
||||
if ( ! curStart.nextSibling || curStart.nextSibling.nodeType != 3 )
|
||||
break ;
|
||||
startOffset -= curStart.length ;
|
||||
curStart = curStart.nextSibling ;
|
||||
}
|
||||
while ( curEnd.nodeType == 3 && endOffset > curEnd.length )
|
||||
{
|
||||
if ( ! curEnd.nextSibling || curEnd.nextSibling.nodeType != 3 )
|
||||
break ;
|
||||
endOffset -= curEnd.length ;
|
||||
curEnd = curEnd.nextSibling ;
|
||||
}
|
||||
this._Range.setStart( curStart, startOffset ) ;
|
||||
this._Range.setEnd( curEnd, endOffset ) ;
|
||||
this._UpdateElementInfo() ;
|
||||
},
|
||||
|
||||
MoveToPosition : function( targetElement, position )
|
||||
{
|
||||
this.SetStart( targetElement, position ) ;
|
||||
this.Collapse( true ) ;
|
||||
},
|
||||
|
||||
/*
|
||||
* Moves the position of the start boundary of the range to a specific position
|
||||
* relatively to a element.
|
||||
* @position:
|
||||
* 1 = After Start <target>^contents</target>
|
||||
* 2 = Before End <target>contents^</target>
|
||||
* 3 = Before Start ^<target>contents</target>
|
||||
* 4 = After End <target>contents</target>^
|
||||
*/
|
||||
SetStart : function( targetElement, position, noInfoUpdate )
|
||||
{
|
||||
var oRange = this._Range ;
|
||||
if ( !oRange )
|
||||
oRange = this._Range = this.CreateRange() ;
|
||||
|
||||
switch( position )
|
||||
{
|
||||
case 1 : // After Start <target>^contents</target>
|
||||
oRange.setStart( targetElement, 0 ) ;
|
||||
break ;
|
||||
|
||||
case 2 : // Before End <target>contents^</target>
|
||||
oRange.setStart( targetElement, targetElement.childNodes.length ) ;
|
||||
break ;
|
||||
|
||||
case 3 : // Before Start ^<target>contents</target>
|
||||
oRange.setStartBefore( targetElement ) ;
|
||||
break ;
|
||||
|
||||
case 4 : // After End <target>contents</target>^
|
||||
oRange.setStartAfter( targetElement ) ;
|
||||
}
|
||||
|
||||
if ( !noInfoUpdate )
|
||||
this._UpdateElementInfo() ;
|
||||
},
|
||||
|
||||
/*
|
||||
* Moves the position of the start boundary of the range to a specific position
|
||||
* relatively to a element.
|
||||
* @position:
|
||||
* 1 = After Start <target>^contents</target>
|
||||
* 2 = Before End <target>contents^</target>
|
||||
* 3 = Before Start ^<target>contents</target>
|
||||
* 4 = After End <target>contents</target>^
|
||||
*/
|
||||
SetEnd : function( targetElement, position, noInfoUpdate )
|
||||
{
|
||||
var oRange = this._Range ;
|
||||
if ( !oRange )
|
||||
oRange = this._Range = this.CreateRange() ;
|
||||
|
||||
switch( position )
|
||||
{
|
||||
case 1 : // After Start <target>^contents</target>
|
||||
oRange.setEnd( targetElement, 0 ) ;
|
||||
break ;
|
||||
|
||||
case 2 : // Before End <target>contents^</target>
|
||||
oRange.setEnd( targetElement, targetElement.childNodes.length ) ;
|
||||
break ;
|
||||
|
||||
case 3 : // Before Start ^<target>contents</target>
|
||||
oRange.setEndBefore( targetElement ) ;
|
||||
break ;
|
||||
|
||||
case 4 : // After End <target>contents</target>^
|
||||
oRange.setEndAfter( targetElement ) ;
|
||||
}
|
||||
|
||||
if ( !noInfoUpdate )
|
||||
this._UpdateElementInfo() ;
|
||||
},
|
||||
|
||||
Expand : function( unit )
|
||||
{
|
||||
var oNode, oSibling ;
|
||||
|
||||
switch ( unit )
|
||||
{
|
||||
// Expand the range to include all inline parent elements if we are
|
||||
// are in their boundary limits.
|
||||
// For example (where [ ] are the range limits):
|
||||
// Before => Some <b>[<i>Some sample text]</i></b>.
|
||||
// After => Some [<b><i>Some sample text</i></b>].
|
||||
case 'inline_elements' :
|
||||
// Expand the start boundary.
|
||||
if ( this._Range.startOffset == 0 )
|
||||
{
|
||||
oNode = this._Range.startContainer ;
|
||||
|
||||
if ( oNode.nodeType != 1 )
|
||||
oNode = oNode.previousSibling ? null : oNode.parentNode ;
|
||||
|
||||
if ( oNode )
|
||||
{
|
||||
while ( FCKListsLib.InlineNonEmptyElements[ oNode.nodeName.toLowerCase() ] )
|
||||
{
|
||||
this._Range.setStartBefore( oNode ) ;
|
||||
|
||||
if ( oNode != oNode.parentNode.firstChild )
|
||||
break ;
|
||||
|
||||
oNode = oNode.parentNode ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expand the end boundary.
|
||||
oNode = this._Range.endContainer ;
|
||||
var offset = this._Range.endOffset ;
|
||||
|
||||
if ( ( oNode.nodeType == 3 && offset >= oNode.nodeValue.length ) || ( oNode.nodeType == 1 && offset >= oNode.childNodes.length ) || ( oNode.nodeType != 1 && oNode.nodeType != 3 ) )
|
||||
{
|
||||
if ( oNode.nodeType != 1 )
|
||||
oNode = oNode.nextSibling ? null : oNode.parentNode ;
|
||||
|
||||
if ( oNode )
|
||||
{
|
||||
while ( FCKListsLib.InlineNonEmptyElements[ oNode.nodeName.toLowerCase() ] )
|
||||
{
|
||||
this._Range.setEndAfter( oNode ) ;
|
||||
|
||||
if ( oNode != oNode.parentNode.lastChild )
|
||||
break ;
|
||||
|
||||
oNode = oNode.parentNode ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break ;
|
||||
|
||||
case 'block_contents' :
|
||||
case 'list_contents' :
|
||||
var boundarySet = FCKListsLib.BlockBoundaries ;
|
||||
if ( unit == 'list_contents' || FCKConfig.EnterMode == 'br' )
|
||||
boundarySet = FCKListsLib.ListBoundaries ;
|
||||
|
||||
if ( this.StartBlock && FCKConfig.EnterMode != 'br' && unit == 'block_contents' )
|
||||
this.SetStart( this.StartBlock, 1 ) ;
|
||||
else
|
||||
{
|
||||
// Get the start node for the current range.
|
||||
oNode = this._Range.startContainer ;
|
||||
|
||||
// If it is an element, get the node right before of it (in source order).
|
||||
if ( oNode.nodeType == 1 )
|
||||
{
|
||||
var lastNode = oNode.childNodes[ this._Range.startOffset ] ;
|
||||
if ( lastNode )
|
||||
oNode = FCKDomTools.GetPreviousSourceNode( lastNode, true ) ;
|
||||
else
|
||||
oNode = oNode.lastChild || oNode ;
|
||||
}
|
||||
|
||||
// We must look for the left boundary, relative to the range
|
||||
// start, which is limited by a block element.
|
||||
while ( oNode
|
||||
&& ( oNode.nodeType != 1
|
||||
|| ( oNode != this.StartBlockLimit
|
||||
&& !boundarySet[ oNode.nodeName.toLowerCase() ] ) ) )
|
||||
{
|
||||
this._Range.setStartBefore( oNode ) ;
|
||||
oNode = oNode.previousSibling || oNode.parentNode ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( this.EndBlock && FCKConfig.EnterMode != 'br' && unit == 'block_contents' && this.EndBlock.nodeName.toLowerCase() != 'li' )
|
||||
this.SetEnd( this.EndBlock, 2 ) ;
|
||||
else
|
||||
{
|
||||
oNode = this._Range.endContainer ;
|
||||
if ( oNode.nodeType == 1 )
|
||||
oNode = oNode.childNodes[ this._Range.endOffset ] || oNode.lastChild ;
|
||||
|
||||
// We must look for the right boundary, relative to the range
|
||||
// end, which is limited by a block element.
|
||||
while ( oNode
|
||||
&& ( oNode.nodeType != 1
|
||||
|| ( oNode != this.StartBlockLimit
|
||||
&& !boundarySet[ oNode.nodeName.toLowerCase() ] ) ) )
|
||||
{
|
||||
this._Range.setEndAfter( oNode ) ;
|
||||
oNode = oNode.nextSibling || oNode.parentNode ;
|
||||
}
|
||||
|
||||
// In EnterMode='br', the end <br> boundary element must
|
||||
// be included in the expanded range.
|
||||
if ( oNode && oNode.nodeName.toLowerCase() == 'br' )
|
||||
this._Range.setEndAfter( oNode ) ;
|
||||
}
|
||||
|
||||
this._UpdateElementInfo() ;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Split the block element for the current range. It deletes the contents
|
||||
* of the range and splits the block in the collapsed position, resulting
|
||||
* in two sucessive blocks. The range is then positioned in the middle of
|
||||
* them.
|
||||
*
|
||||
* It returns and object with the following properties:
|
||||
* - PreviousBlock : a reference to the block element that preceeds
|
||||
* the range after the split.
|
||||
* - NextBlock : a reference to the block element that follows the
|
||||
* range after the split.
|
||||
* - WasStartOfBlock : a boolean indicating that the range was
|
||||
* originaly at the start of the block.
|
||||
* - WasEndOfBlock : a boolean indicating that the range was originaly
|
||||
* at the end of the block.
|
||||
*
|
||||
* If the range was originaly at the start of the block, no split will happen
|
||||
* and the PreviousBlock value will be null. The same is valid for the
|
||||
* NextBlock value if the range was at the end of the block.
|
||||
*/
|
||||
SplitBlock : function( forceBlockTag )
|
||||
{
|
||||
var blockTag = forceBlockTag || FCKConfig.EnterMode ;
|
||||
|
||||
if ( !this._Range )
|
||||
this.MoveToSelection() ;
|
||||
|
||||
// The range boundaries must be in the same "block limit" element.
|
||||
if ( this.StartBlockLimit == this.EndBlockLimit )
|
||||
{
|
||||
// Get the current blocks.
|
||||
var eStartBlock = this.StartBlock ;
|
||||
var eEndBlock = this.EndBlock ;
|
||||
var oElementPath = null ;
|
||||
|
||||
if ( blockTag != 'br' )
|
||||
{
|
||||
if ( !eStartBlock )
|
||||
{
|
||||
eStartBlock = this.FixBlock( true, blockTag ) ;
|
||||
eEndBlock = this.EndBlock ; // FixBlock may have fixed the EndBlock too.
|
||||
}
|
||||
|
||||
if ( !eEndBlock )
|
||||
eEndBlock = this.FixBlock( false, blockTag ) ;
|
||||
}
|
||||
|
||||
// Get the range position.
|
||||
var bIsStartOfBlock = ( eStartBlock != null && this.CheckStartOfBlock() ) ;
|
||||
var bIsEndOfBlock = ( eEndBlock != null && this.CheckEndOfBlock() ) ;
|
||||
|
||||
// Delete the current contents.
|
||||
if ( !this.CheckIsEmpty() )
|
||||
this.DeleteContents() ;
|
||||
|
||||
if ( eStartBlock && eEndBlock && eStartBlock == eEndBlock )
|
||||
{
|
||||
if ( bIsEndOfBlock )
|
||||
{
|
||||
oElementPath = new FCKElementPath( this.StartContainer ) ;
|
||||
this.MoveToPosition( eEndBlock, 4 ) ;
|
||||
eEndBlock = null ;
|
||||
}
|
||||
else if ( bIsStartOfBlock )
|
||||
{
|
||||
oElementPath = new FCKElementPath( this.StartContainer ) ;
|
||||
this.MoveToPosition( eStartBlock, 3 ) ;
|
||||
eStartBlock = null ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Extract the contents of the block from the selection point to the end of its contents.
|
||||
this.SetEnd( eStartBlock, 2 ) ;
|
||||
var eDocFrag = this.ExtractContents() ;
|
||||
|
||||
// Duplicate the block element after it.
|
||||
eEndBlock = eStartBlock.cloneNode( false ) ;
|
||||
eEndBlock.removeAttribute( 'id', false ) ;
|
||||
|
||||
// Place the extracted contents in the duplicated block.
|
||||
eDocFrag.AppendTo( eEndBlock ) ;
|
||||
|
||||
FCKDomTools.InsertAfterNode( eStartBlock, eEndBlock ) ;
|
||||
|
||||
this.MoveToPosition( eStartBlock, 4 ) ;
|
||||
|
||||
// In Gecko, the last child node must be a bogus <br>.
|
||||
// Note: bogus <br> added under <ul> or <ol> would cause lists to be incorrectly rendered.
|
||||
if ( FCKBrowserInfo.IsGecko &&
|
||||
! eStartBlock.nodeName.IEquals( ['ul', 'ol'] ) )
|
||||
FCKTools.AppendBogusBr( eStartBlock ) ;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
PreviousBlock : eStartBlock,
|
||||
NextBlock : eEndBlock,
|
||||
WasStartOfBlock : bIsStartOfBlock,
|
||||
WasEndOfBlock : bIsEndOfBlock,
|
||||
ElementPath : oElementPath
|
||||
} ;
|
||||
}
|
||||
|
||||
return null ;
|
||||
},
|
||||
|
||||
// Transform a block without a block tag in a valid block (orphan text in the body or td, usually).
|
||||
FixBlock : function( isStart, blockTag )
|
||||
{
|
||||
// Bookmark the range so we can restore it later.
|
||||
var oBookmark = this.CreateBookmark() ;
|
||||
|
||||
// Collapse the range to the requested ending boundary.
|
||||
this.Collapse( isStart ) ;
|
||||
|
||||
// Expands it to the block contents.
|
||||
this.Expand( 'block_contents' ) ;
|
||||
|
||||
// Create the fixed block.
|
||||
var oFixedBlock = this.Window.document.createElement( blockTag ) ;
|
||||
|
||||
// Move the contents of the temporary range to the fixed block.
|
||||
this.ExtractContents().AppendTo( oFixedBlock ) ;
|
||||
FCKDomTools.TrimNode( oFixedBlock ) ;
|
||||
|
||||
// If the fixed block is empty (not counting bookmark nodes)
|
||||
// Add a <br /> inside to expand it.
|
||||
if ( FCKDomTools.CheckIsEmptyElement(oFixedBlock, function( element ) { return element.getAttribute('_fck_bookmark') != 'true' ; } )
|
||||
&& FCKBrowserInfo.IsGeckoLike )
|
||||
FCKTools.AppendBogusBr( oFixedBlock ) ;
|
||||
|
||||
// Insert the fixed block into the DOM.
|
||||
this.InsertNode( oFixedBlock ) ;
|
||||
|
||||
// Move the range back to the bookmarked place.
|
||||
this.MoveToBookmark( oBookmark ) ;
|
||||
|
||||
return oFixedBlock ;
|
||||
},
|
||||
|
||||
Release : function( preserveWindow )
|
||||
{
|
||||
if ( !preserveWindow )
|
||||
this.Window = null ;
|
||||
|
||||
this.StartNode = null ;
|
||||
this.StartContainer = null ;
|
||||
this.StartBlock = null ;
|
||||
this.StartBlockLimit = null ;
|
||||
this.EndNode = null ;
|
||||
this.EndContainer = null ;
|
||||
this.EndBlock = null ;
|
||||
this.EndBlockLimit = null ;
|
||||
this._Range = null ;
|
||||
this._Cache = null ;
|
||||
},
|
||||
|
||||
CheckHasRange : function()
|
||||
{
|
||||
return !!this._Range ;
|
||||
},
|
||||
|
||||
GetTouchedStartNode : function()
|
||||
{
|
||||
var range = this._Range ;
|
||||
var container = range.startContainer ;
|
||||
|
||||
if ( range.collapsed || container.nodeType != 1 )
|
||||
return container ;
|
||||
|
||||
return container.childNodes[ range.startOffset ] || container ;
|
||||
},
|
||||
|
||||
GetTouchedEndNode : function()
|
||||
{
|
||||
var range = this._Range ;
|
||||
var container = range.endContainer ;
|
||||
|
||||
if ( range.collapsed || container.nodeType != 1 )
|
||||
return container ;
|
||||
|
||||
return container.childNodes[ range.endOffset - 1 ] || container ;
|
||||
}
|
||||
} ;
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Class for working with a selection range, much like the W3C DOM Range, but
|
||||
* it is not intended to be an implementation of the W3C interface.
|
||||
* (Gecko Implementation)
|
||||
*/
|
||||
|
||||
FCKDomRange.prototype.MoveToSelection = function()
|
||||
{
|
||||
this.Release( true ) ;
|
||||
|
||||
var oSel = this.Window.getSelection() ;
|
||||
|
||||
if ( oSel && oSel.rangeCount > 0 )
|
||||
{
|
||||
this._Range = FCKW3CRange.CreateFromRange( this.Window.document, oSel.getRangeAt(0) ) ;
|
||||
this._UpdateElementInfo() ;
|
||||
}
|
||||
else
|
||||
if ( this.Window.document )
|
||||
this.MoveToElementStart( this.Window.document.body ) ;
|
||||
}
|
||||
|
||||
FCKDomRange.prototype.Select = function()
|
||||
{
|
||||
var oRange = this._Range ;
|
||||
if ( oRange )
|
||||
{
|
||||
var startContainer = oRange.startContainer ;
|
||||
|
||||
// If we have a collapsed range, inside an empty element, we must add
|
||||
// something to it, otherwise the caret will not be visible.
|
||||
if ( oRange.collapsed && startContainer.nodeType == 1 && startContainer.childNodes.length == 0 )
|
||||
startContainer.appendChild( oRange._Document.createTextNode('') ) ;
|
||||
|
||||
var oDocRange = this.Window.document.createRange() ;
|
||||
oDocRange.setStart( startContainer, oRange.startOffset ) ;
|
||||
|
||||
try
|
||||
{
|
||||
oDocRange.setEnd( oRange.endContainer, oRange.endOffset ) ;
|
||||
}
|
||||
catch ( e )
|
||||
{
|
||||
// There is a bug in Firefox implementation (it would be too easy
|
||||
// otherwise). The new start can't be after the end (W3C says it can).
|
||||
// So, let's create a new range and collapse it to the desired point.
|
||||
if ( e.toString().Contains( 'NS_ERROR_ILLEGAL_VALUE' ) )
|
||||
{
|
||||
oRange.collapse( true ) ;
|
||||
oDocRange.setEnd( oRange.endContainer, oRange.endOffset ) ;
|
||||
}
|
||||
else
|
||||
throw( e ) ;
|
||||
}
|
||||
|
||||
var oSel = this.Window.getSelection() ;
|
||||
oSel.removeAllRanges() ;
|
||||
|
||||
// We must add a clone otherwise Firefox will have rendering issues.
|
||||
oSel.addRange( oDocRange ) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Not compatible with bookmark created with CreateBookmark2.
|
||||
// The bookmark nodes will be deleted from the document.
|
||||
FCKDomRange.prototype.SelectBookmark = function( bookmark )
|
||||
{
|
||||
var domRange = this.Window.document.createRange() ;
|
||||
|
||||
var startNode = this.GetBookmarkNode( bookmark, true ) ;
|
||||
var endNode = this.GetBookmarkNode( bookmark, false ) ;
|
||||
|
||||
domRange.setStart( startNode.parentNode, FCKDomTools.GetIndexOf( startNode ) ) ;
|
||||
FCKDomTools.RemoveNode( startNode ) ;
|
||||
|
||||
if ( endNode )
|
||||
{
|
||||
domRange.setEnd( endNode.parentNode, FCKDomTools.GetIndexOf( endNode ) ) ;
|
||||
FCKDomTools.RemoveNode( endNode ) ;
|
||||
}
|
||||
|
||||
var selection = this.Window.getSelection() ;
|
||||
selection.removeAllRanges() ;
|
||||
selection.addRange( domRange ) ;
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Class for working with a selection range, much like the W3C DOM Range, but
|
||||
* it is not intended to be an implementation of the W3C interface.
|
||||
* (IE Implementation)
|
||||
*/
|
||||
|
||||
FCKDomRange.prototype.MoveToSelection = function()
|
||||
{
|
||||
this.Release( true ) ;
|
||||
|
||||
this._Range = new FCKW3CRange( this.Window.document ) ;
|
||||
|
||||
var oSel = this.Window.document.selection ;
|
||||
|
||||
if ( oSel.type != 'Control' )
|
||||
{
|
||||
var eMarkerStart = this._GetSelectionMarkerTag( true ) ;
|
||||
var eMarkerEnd = this._GetSelectionMarkerTag( false ) ;
|
||||
|
||||
if ( !eMarkerStart && !eMarkerEnd )
|
||||
{
|
||||
this._Range.setStart( this.Window.document.body, 0 ) ;
|
||||
this._UpdateElementInfo() ;
|
||||
return ;
|
||||
}
|
||||
|
||||
// Set the start boundary.
|
||||
this._Range.setStart( eMarkerStart.parentNode, FCKDomTools.GetIndexOf( eMarkerStart ) ) ;
|
||||
eMarkerStart.parentNode.removeChild( eMarkerStart ) ;
|
||||
|
||||
// Set the end boundary.
|
||||
this._Range.setEnd( eMarkerEnd.parentNode, FCKDomTools.GetIndexOf( eMarkerEnd ) ) ;
|
||||
eMarkerEnd.parentNode.removeChild( eMarkerEnd ) ;
|
||||
|
||||
this._UpdateElementInfo() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
var oControl = oSel.createRange().item(0) ;
|
||||
|
||||
if ( oControl )
|
||||
{
|
||||
this._Range.setStartBefore( oControl ) ;
|
||||
this._Range.setEndAfter( oControl ) ;
|
||||
this._UpdateElementInfo() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FCKDomRange.prototype.Select = function( forceExpand )
|
||||
{
|
||||
if ( this._Range )
|
||||
this.SelectBookmark( this.CreateBookmark( true ), forceExpand ) ;
|
||||
}
|
||||
|
||||
// Not compatible with bookmark created with CreateBookmark2.
|
||||
// The bookmark nodes will be deleted from the document.
|
||||
FCKDomRange.prototype.SelectBookmark = function( bookmark, forceExpand )
|
||||
{
|
||||
var bIsCollapsed = this.CheckIsCollapsed() ;
|
||||
var bIsStartMakerAlone ;
|
||||
var dummySpan ;
|
||||
|
||||
// Create marker tags for the start and end boundaries.
|
||||
var eStartMarker = this.GetBookmarkNode( bookmark, true ) ;
|
||||
|
||||
if ( !eStartMarker )
|
||||
return ;
|
||||
|
||||
var eEndMarker ;
|
||||
if ( !bIsCollapsed )
|
||||
eEndMarker = this.GetBookmarkNode( bookmark, false ) ;
|
||||
|
||||
// Create the main range which will be used for the selection.
|
||||
var oIERange = this.Window.document.body.createTextRange() ;
|
||||
|
||||
// Position the range at the start boundary.
|
||||
oIERange.moveToElementText( eStartMarker ) ;
|
||||
oIERange.moveStart( 'character', 1 ) ;
|
||||
|
||||
if ( eEndMarker )
|
||||
{
|
||||
// Create a tool range for the end.
|
||||
var oIERangeEnd = this.Window.document.body.createTextRange() ;
|
||||
|
||||
// Position the tool range at the end.
|
||||
oIERangeEnd.moveToElementText( eEndMarker ) ;
|
||||
|
||||
// Move the end boundary of the main range to match the tool range.
|
||||
oIERange.setEndPoint( 'EndToEnd', oIERangeEnd ) ;
|
||||
oIERange.moveEnd( 'character', -1 ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
bIsStartMakerAlone = ( forceExpand || !eStartMarker.previousSibling || eStartMarker.previousSibling.nodeName.toLowerCase() == 'br' ) && !eStartMarker.nextSibing ;
|
||||
|
||||
// Append a temporary <span></span> before the selection.
|
||||
// This is needed to avoid IE destroying selections inside empty
|
||||
// inline elements, like <b></b> (#253).
|
||||
// It is also needed when placing the selection right after an inline
|
||||
// element to avoid the selection moving inside of it.
|
||||
dummySpan = this.Window.document.createElement( 'span' ) ;
|
||||
dummySpan.innerHTML = '' ; // Zero Width No-Break Space (U+FEFF). See #1359.
|
||||
eStartMarker.parentNode.insertBefore( dummySpan, eStartMarker ) ;
|
||||
|
||||
if ( bIsStartMakerAlone )
|
||||
{
|
||||
// To expand empty blocks or line spaces after <br>, we need
|
||||
// instead to have any char, which will be later deleted using the
|
||||
// selection.
|
||||
// \ufeff = Zero Width No-Break Space (U+FEFF). See #1359.
|
||||
eStartMarker.parentNode.insertBefore( this.Window.document.createTextNode( '\ufeff' ), eStartMarker ) ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !this._Range )
|
||||
this._Range = this.CreateRange() ;
|
||||
|
||||
// Remove the markers (reset the position, because of the changes in the DOM tree).
|
||||
this._Range.setStartBefore( eStartMarker ) ;
|
||||
eStartMarker.parentNode.removeChild( eStartMarker ) ;
|
||||
|
||||
if ( bIsCollapsed )
|
||||
{
|
||||
if ( bIsStartMakerAlone )
|
||||
{
|
||||
// Move the selection start to include the temporary .
|
||||
oIERange.moveStart( 'character', -1 ) ;
|
||||
|
||||
oIERange.select() ;
|
||||
|
||||
// Remove our temporary stuff.
|
||||
this.Window.document.selection.clear() ;
|
||||
}
|
||||
else
|
||||
oIERange.select() ;
|
||||
|
||||
FCKDomTools.RemoveNode( dummySpan ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._Range.setEndBefore( eEndMarker ) ;
|
||||
eEndMarker.parentNode.removeChild( eEndMarker ) ;
|
||||
oIERange.select() ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKDomRange.prototype._GetSelectionMarkerTag = function( toStart )
|
||||
{
|
||||
var doc = this.Window.document ;
|
||||
var selection = doc.selection ;
|
||||
|
||||
// Get a range for the start boundary.
|
||||
var oRange ;
|
||||
|
||||
// IE may throw an "unspecified error" on some cases (it happened when
|
||||
// loading _samples/default.html), so try/catch.
|
||||
try
|
||||
{
|
||||
oRange = selection.createRange() ;
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
return null ;
|
||||
}
|
||||
|
||||
// IE might take the range object to the main window instead of inside the editor iframe window.
|
||||
// This is known to happen when the editor window has not been selected before (See #933).
|
||||
// We need to avoid that.
|
||||
if ( oRange.parentElement().document != doc )
|
||||
return null ;
|
||||
|
||||
oRange.collapse( toStart === true ) ;
|
||||
|
||||
// Paste a marker element at the collapsed range and get it from the DOM.
|
||||
var sMarkerId = 'fck_dom_range_temp_' + (new Date()).valueOf() + '_' + Math.floor(Math.random()*1000) ;
|
||||
oRange.pasteHTML( '<span id="' + sMarkerId + '"></span>' ) ;
|
||||
|
||||
return doc.getElementById( sMarkerId ) ;
|
||||
}
|
||||
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* This class can be used to interate through nodes inside a range.
|
||||
*
|
||||
* During interation, the provided range can become invalid, due to document
|
||||
* mutations, so CreateBookmark() used to restore it after processing, if
|
||||
* needed.
|
||||
*/
|
||||
|
||||
var FCKDomRangeIterator = function( range )
|
||||
{
|
||||
/**
|
||||
* The FCKDomRange object that marks the interation boundaries.
|
||||
*/
|
||||
this.Range = range ;
|
||||
|
||||
/**
|
||||
* Indicates that <br> elements must be used as paragraph boundaries.
|
||||
*/
|
||||
this.ForceBrBreak = false ;
|
||||
|
||||
/**
|
||||
* Guarantees that the iterator will always return "real" block elements.
|
||||
* If "false", elements like <li>, <th> and <td> are returned. If "true", a
|
||||
* dedicated block element block element will be created inside those
|
||||
* elements to hold the selected content.
|
||||
*/
|
||||
this.EnforceRealBlocks = false ;
|
||||
}
|
||||
|
||||
FCKDomRangeIterator.CreateFromSelection = function( targetWindow )
|
||||
{
|
||||
var range = new FCKDomRange( targetWindow ) ;
|
||||
range.MoveToSelection() ;
|
||||
return new FCKDomRangeIterator( range ) ;
|
||||
}
|
||||
|
||||
FCKDomRangeIterator.prototype =
|
||||
{
|
||||
/**
|
||||
* Get the next paragraph element. It automatically breaks the document
|
||||
* when necessary to generate block elements for the paragraphs.
|
||||
*/
|
||||
GetNextParagraph : function()
|
||||
{
|
||||
// The block element to be returned.
|
||||
var block ;
|
||||
|
||||
// The range object used to identify the paragraph contents.
|
||||
var range ;
|
||||
|
||||
// Indicated that the current element in the loop is the last one.
|
||||
var isLast ;
|
||||
|
||||
// Instructs to cleanup remaining BRs.
|
||||
var removePreviousBr ;
|
||||
var removeLastBr ;
|
||||
|
||||
var boundarySet = this.ForceBrBreak ? FCKListsLib.ListBoundaries : FCKListsLib.BlockBoundaries ;
|
||||
|
||||
// This is the first iteration. Let's initialize it.
|
||||
if ( !this._LastNode )
|
||||
{
|
||||
var range = this.Range.Clone() ;
|
||||
range.Expand( this.ForceBrBreak ? 'list_contents' : 'block_contents' ) ;
|
||||
|
||||
this._NextNode = range.GetTouchedStartNode() ;
|
||||
this._LastNode = range.GetTouchedEndNode() ;
|
||||
|
||||
// Let's reuse this variable.
|
||||
range = null ;
|
||||
}
|
||||
|
||||
var currentNode = this._NextNode ;
|
||||
var lastNode = this._LastNode ;
|
||||
|
||||
this._NextNode = null ;
|
||||
|
||||
while ( currentNode )
|
||||
{
|
||||
// closeRange indicates that a paragraph boundary has been found,
|
||||
// so the range can be closed.
|
||||
var closeRange = false ;
|
||||
|
||||
// includeNode indicates that the current node is good to be part
|
||||
// of the range. By default, any non-element node is ok for it.
|
||||
var includeNode = ( currentNode.nodeType != 1 ) ;
|
||||
|
||||
var continueFromSibling = false ;
|
||||
|
||||
// If it is an element node, let's check if it can be part of the
|
||||
// range.
|
||||
if ( !includeNode )
|
||||
{
|
||||
var nodeName = currentNode.nodeName.toLowerCase() ;
|
||||
|
||||
if ( boundarySet[ nodeName ] && ( !FCKBrowserInfo.IsIE || currentNode.scopeName == 'HTML' ) )
|
||||
{
|
||||
// <br> boundaries must be part of the range. It will
|
||||
// happen only if ForceBrBreak.
|
||||
if ( nodeName == 'br' )
|
||||
includeNode = true ;
|
||||
else if ( !range && currentNode.childNodes.length == 0 && nodeName != 'hr' )
|
||||
{
|
||||
// If we have found an empty block, and haven't started
|
||||
// the range yet, it means we must return this block.
|
||||
block = currentNode ;
|
||||
isLast = currentNode == lastNode ;
|
||||
break ;
|
||||
}
|
||||
|
||||
// The range must finish right before the boundary,
|
||||
// including possibly skipped empty spaces. (#1603)
|
||||
if ( range )
|
||||
{
|
||||
range.SetEnd( currentNode, 3, true ) ;
|
||||
|
||||
// The found boundary must be set as the next one at this
|
||||
// point. (#1717)
|
||||
if ( nodeName != 'br' )
|
||||
this._NextNode = FCKDomTools.GetNextSourceNode( currentNode, true, null, lastNode ) ;
|
||||
}
|
||||
|
||||
closeRange = true ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we have child nodes, let's check them.
|
||||
if ( currentNode.firstChild )
|
||||
{
|
||||
// If we don't have a range yet, let's start it.
|
||||
if ( !range )
|
||||
{
|
||||
range = new FCKDomRange( this.Range.Window ) ;
|
||||
range.SetStart( currentNode, 3, true ) ;
|
||||
}
|
||||
|
||||
currentNode = currentNode.firstChild ;
|
||||
continue ;
|
||||
}
|
||||
includeNode = true ;
|
||||
}
|
||||
}
|
||||
else if ( currentNode.nodeType == 3 )
|
||||
{
|
||||
// Ignore normal whitespaces (i.e. not including or
|
||||
// other unicode whitespaces) before/after a block node.
|
||||
if ( /^[\r\n\t ]+$/.test( currentNode.nodeValue ) )
|
||||
includeNode = false ;
|
||||
}
|
||||
|
||||
// The current node is good to be part of the range and we are
|
||||
// starting a new range, initialize it first.
|
||||
if ( includeNode && !range )
|
||||
{
|
||||
range = new FCKDomRange( this.Range.Window ) ;
|
||||
range.SetStart( currentNode, 3, true ) ;
|
||||
}
|
||||
|
||||
// The last node has been found.
|
||||
isLast = ( ( !closeRange || includeNode ) && currentNode == lastNode ) ;
|
||||
// isLast = ( currentNode == lastNode && ( currentNode.nodeType != 1 || currentNode.childNodes.length == 0 ) ) ;
|
||||
|
||||
// If we are in an element boundary, let's check if it is time
|
||||
// to close the range, otherwise we include the parent within it.
|
||||
if ( range && !closeRange )
|
||||
{
|
||||
while ( !currentNode.nextSibling && !isLast )
|
||||
{
|
||||
var parentNode = currentNode.parentNode ;
|
||||
|
||||
if ( boundarySet[ parentNode.nodeName.toLowerCase() ] )
|
||||
{
|
||||
closeRange = true ;
|
||||
isLast = isLast || ( parentNode == lastNode ) ;
|
||||
break ;
|
||||
}
|
||||
|
||||
currentNode = parentNode ;
|
||||
includeNode = true ;
|
||||
isLast = ( currentNode == lastNode ) ;
|
||||
continueFromSibling = true ;
|
||||
}
|
||||
}
|
||||
|
||||
// Now finally include the node.
|
||||
if ( includeNode )
|
||||
range.SetEnd( currentNode, 4, true ) ;
|
||||
|
||||
// We have found a block boundary. Let's close the range and move out of the
|
||||
// loop.
|
||||
if ( ( closeRange || isLast ) && range )
|
||||
{
|
||||
range._UpdateElementInfo() ;
|
||||
|
||||
if ( range.StartNode == range.EndNode
|
||||
&& range.StartNode.parentNode == range.StartBlockLimit
|
||||
&& range.StartNode.getAttribute && range.StartNode.getAttribute( '_fck_bookmark' ) )
|
||||
range = null ;
|
||||
else
|
||||
break ;
|
||||
}
|
||||
|
||||
if ( isLast )
|
||||
break ;
|
||||
|
||||
currentNode = FCKDomTools.GetNextSourceNode( currentNode, continueFromSibling, null, lastNode ) ;
|
||||
}
|
||||
|
||||
// Now, based on the processed range, look for (or create) the block to be returned.
|
||||
if ( !block )
|
||||
{
|
||||
// If no range has been found, this is the end.
|
||||
if ( !range )
|
||||
{
|
||||
this._NextNode = null ;
|
||||
return null ;
|
||||
}
|
||||
|
||||
block = range.StartBlock ;
|
||||
|
||||
if ( !block
|
||||
&& !this.EnforceRealBlocks
|
||||
&& range.StartBlockLimit.nodeName.IEquals( 'DIV', 'TH', 'TD' )
|
||||
&& range.CheckStartOfBlock()
|
||||
&& range.CheckEndOfBlock() )
|
||||
{
|
||||
block = range.StartBlockLimit ;
|
||||
}
|
||||
else if ( !block || ( this.EnforceRealBlocks && block.nodeName.toLowerCase() == 'li' ) )
|
||||
{
|
||||
// Create the fixed block.
|
||||
block = this.Range.Window.document.createElement( FCKConfig.EnterMode == 'p' ? 'p' : 'div' ) ;
|
||||
|
||||
// Move the contents of the temporary range to the fixed block.
|
||||
range.ExtractContents().AppendTo( block ) ;
|
||||
FCKDomTools.TrimNode( block ) ;
|
||||
|
||||
// Insert the fixed block into the DOM.
|
||||
range.InsertNode( block ) ;
|
||||
|
||||
removePreviousBr = true ;
|
||||
removeLastBr = true ;
|
||||
}
|
||||
else if ( block.nodeName.toLowerCase() != 'li' )
|
||||
{
|
||||
// If the range doesn't includes the entire contents of the
|
||||
// block, we must split it, isolating the range in a dedicated
|
||||
// block.
|
||||
if ( !range.CheckStartOfBlock() || !range.CheckEndOfBlock() )
|
||||
{
|
||||
// The resulting block will be a clone of the current one.
|
||||
block = block.cloneNode( false ) ;
|
||||
|
||||
// Extract the range contents, moving it to the new block.
|
||||
range.ExtractContents().AppendTo( block ) ;
|
||||
FCKDomTools.TrimNode( block ) ;
|
||||
|
||||
// Split the block. At this point, the range will be in the
|
||||
// right position for our intents.
|
||||
var splitInfo = range.SplitBlock() ;
|
||||
|
||||
removePreviousBr = !splitInfo.WasStartOfBlock ;
|
||||
removeLastBr = !splitInfo.WasEndOfBlock ;
|
||||
|
||||
// Insert the new block into the DOM.
|
||||
range.InsertNode( block ) ;
|
||||
}
|
||||
}
|
||||
else if ( !isLast )
|
||||
{
|
||||
// LIs are returned as is, with all their children (due to the
|
||||
// nested lists). But, the next node is the node right after
|
||||
// the current range, which could be an <li> child (nested
|
||||
// lists) or the next sibling <li>.
|
||||
|
||||
this._NextNode = block == lastNode ? null : FCKDomTools.GetNextSourceNode( range.EndNode, true, null, lastNode ) ;
|
||||
return block ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( removePreviousBr )
|
||||
{
|
||||
var previousSibling = block.previousSibling ;
|
||||
if ( previousSibling && previousSibling.nodeType == 1 )
|
||||
{
|
||||
if ( previousSibling.nodeName.toLowerCase() == 'br' )
|
||||
previousSibling.parentNode.removeChild( previousSibling ) ;
|
||||
else if ( previousSibling.lastChild && previousSibling.lastChild.nodeName.IEquals( 'br' ) )
|
||||
previousSibling.removeChild( previousSibling.lastChild ) ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( removeLastBr )
|
||||
{
|
||||
var lastChild = block.lastChild ;
|
||||
if ( lastChild && lastChild.nodeType == 1 && lastChild.nodeName.toLowerCase() == 'br' )
|
||||
block.removeChild( lastChild ) ;
|
||||
}
|
||||
|
||||
// Get a reference for the next element. This is important because the
|
||||
// above block can be removed or changed, so we can rely on it for the
|
||||
// next interation.
|
||||
if ( !this._NextNode )
|
||||
this._NextNode = ( isLast || block == lastNode ) ? null : FCKDomTools.GetNextSourceNode( block, true, null, lastNode ) ;
|
||||
|
||||
return block ;
|
||||
}
|
||||
} ;
|
||||
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKEditingArea Class: renders an editable area.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {String} targetElement The element that will hold the editing area. Any child element present in the target will be deleted.
|
||||
*/
|
||||
var FCKEditingArea = function( targetElement )
|
||||
{
|
||||
this.TargetElement = targetElement ;
|
||||
this.Mode = FCK_EDITMODE_WYSIWYG ;
|
||||
|
||||
if ( FCK.IECleanup )
|
||||
FCK.IECleanup.AddItem( this, FCKEditingArea_Cleanup ) ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {String} html The complete HTML for the page, including DOCTYPE and the <html> tag.
|
||||
*/
|
||||
FCKEditingArea.prototype.Start = function( html, secondCall )
|
||||
{
|
||||
var eTargetElement = this.TargetElement ;
|
||||
var oTargetDocument = FCKTools.GetElementDocument( eTargetElement ) ;
|
||||
|
||||
// Remove all child nodes from the target.
|
||||
while( eTargetElement.firstChild )
|
||||
eTargetElement.removeChild( eTargetElement.firstChild ) ;
|
||||
|
||||
if ( this.Mode == FCK_EDITMODE_WYSIWYG )
|
||||
{
|
||||
// For FF, document.domain must be set only when different, otherwhise
|
||||
// we'll strangely have "Permission denied" issues.
|
||||
if ( FCK_IS_CUSTOM_DOMAIN )
|
||||
html = '<script>document.domain="' + FCK_RUNTIME_DOMAIN + '";</script>' + html ;
|
||||
|
||||
// IE has a bug with the <base> tag... it must have a </base> closer,
|
||||
// otherwise the all successive tags will be set as children nodes of the <base>.
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
html = html.replace( /(<base[^>]*?)\s*\/?>(?!\s*<\/base>)/gi, '$1></base>' ) ;
|
||||
else if ( !secondCall )
|
||||
{
|
||||
// Gecko moves some tags out of the body to the head, so we must use
|
||||
// innerHTML to set the body contents (SF BUG 1526154).
|
||||
|
||||
// Extract the BODY contents from the html.
|
||||
var oMatchBefore = html.match( FCKRegexLib.BeforeBody ) ;
|
||||
var oMatchAfter = html.match( FCKRegexLib.AfterBody ) ;
|
||||
|
||||
if ( oMatchBefore && oMatchAfter )
|
||||
{
|
||||
var sBody = html.substr( oMatchBefore[1].length,
|
||||
html.length - oMatchBefore[1].length - oMatchAfter[1].length ) ; // This is the BODY tag contents.
|
||||
|
||||
html =
|
||||
oMatchBefore[1] + // This is the HTML until the <body...> tag, inclusive.
|
||||
' ' +
|
||||
oMatchAfter[1] ; // This is the HTML from the </body> tag, inclusive.
|
||||
|
||||
// If nothing in the body, place a BOGUS tag so the cursor will appear.
|
||||
if ( FCKBrowserInfo.IsGecko && ( sBody.length == 0 || FCKRegexLib.EmptyParagraph.test( sBody ) ) )
|
||||
sBody = '<br type="_moz">' ;
|
||||
|
||||
this._BodyHTML = sBody ;
|
||||
|
||||
}
|
||||
else
|
||||
this._BodyHTML = html ; // Invalid HTML input.
|
||||
}
|
||||
|
||||
// Create the editing area IFRAME.
|
||||
var oIFrame = this.IFrame = oTargetDocument.createElement( 'iframe' ) ;
|
||||
|
||||
// IE: Avoid JavaScript errors thrown by the editing are source (like tags events).
|
||||
// See #1055.
|
||||
var sOverrideError = '<script type="text/javascript" _fcktemp="true">window.onerror=function(){return true;};</script>' ;
|
||||
|
||||
oIFrame.frameBorder = 0 ;
|
||||
oIFrame.style.width = oIFrame.style.height = '100%' ;
|
||||
|
||||
if ( FCK_IS_CUSTOM_DOMAIN && FCKBrowserInfo.IsIE )
|
||||
{
|
||||
window._FCKHtmlToLoad = html.replace( /<head>/i, '<head>' + sOverrideError ) ;
|
||||
oIFrame.src = 'javascript:void( (function(){' +
|
||||
'document.open() ;' +
|
||||
'document.domain="' + document.domain + '" ;' +
|
||||
'document.write( window.parent._FCKHtmlToLoad );' +
|
||||
'document.close() ;' +
|
||||
'window.parent._FCKHtmlToLoad = null ;' +
|
||||
'})() )' ;
|
||||
}
|
||||
else if ( !FCKBrowserInfo.IsGecko )
|
||||
{
|
||||
// Firefox will render the tables inside the body in Quirks mode if the
|
||||
// source of the iframe is set to javascript. see #515
|
||||
oIFrame.src = 'javascript:void(0)' ;
|
||||
}
|
||||
|
||||
// Append the new IFRAME to the target. For IE, it must be done after
|
||||
// setting the "src", to avoid the "secure/unsecure" message under HTTPS.
|
||||
eTargetElement.appendChild( oIFrame ) ;
|
||||
|
||||
// Get the window and document objects used to interact with the newly created IFRAME.
|
||||
this.Window = oIFrame.contentWindow ;
|
||||
|
||||
// IE: Avoid JavaScript errors thrown by the editing are source (like tags events).
|
||||
// TODO: This error handler is not being fired.
|
||||
// this.Window.onerror = function() { alert( 'Error!' ) ; return true ; }
|
||||
|
||||
if ( !FCK_IS_CUSTOM_DOMAIN || !FCKBrowserInfo.IsIE )
|
||||
{
|
||||
var oDoc = this.Window.document ;
|
||||
|
||||
oDoc.open() ;
|
||||
oDoc.write( html.replace( /<head>/i, '<head>' + sOverrideError ) ) ;
|
||||
oDoc.close() ;
|
||||
}
|
||||
|
||||
if ( FCKBrowserInfo.IsAIR )
|
||||
FCKAdobeAIR.EditingArea_Start( oDoc, html ) ;
|
||||
|
||||
// Firefox 1.0.x is buggy... ohh yes... so let's do it two times and it
|
||||
// will magically work.
|
||||
if ( FCKBrowserInfo.IsGecko10 && !secondCall )
|
||||
{
|
||||
this.Start( html, true ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
if ( oIFrame.readyState && oIFrame.readyState != 'completed' )
|
||||
{
|
||||
var editArea = this ;
|
||||
|
||||
// Using a IE alternative for DOMContentLoaded, similar to the
|
||||
// solution proposed at http://javascript.nwbox.com/IEContentLoaded/
|
||||
setTimeout( function()
|
||||
{
|
||||
try
|
||||
{
|
||||
editArea.Window.document.documentElement.doScroll("left") ;
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
setTimeout( arguments.callee, 0 ) ;
|
||||
return ;
|
||||
}
|
||||
editArea.Window._FCKEditingArea = editArea ;
|
||||
FCKEditingArea_CompleteStart.call( editArea.Window ) ;
|
||||
}, 0 ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Window._FCKEditingArea = this ;
|
||||
|
||||
// FF 1.0.x is buggy... we must wait a lot to enable editing because
|
||||
// sometimes the content simply disappears, for example when pasting
|
||||
// "bla1!<img src='some_url'>!bla2" in the source and then switching
|
||||
// back to design.
|
||||
if ( FCKBrowserInfo.IsGecko10 )
|
||||
this.Window.setTimeout( FCKEditingArea_CompleteStart, 500 ) ;
|
||||
else
|
||||
FCKEditingArea_CompleteStart.call( this.Window ) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var eTextarea = this.Textarea = oTargetDocument.createElement( 'textarea' ) ;
|
||||
eTextarea.className = 'SourceField' ;
|
||||
eTextarea.dir = 'ltr' ;
|
||||
FCKDomTools.SetElementStyles( eTextarea,
|
||||
{
|
||||
width : '100%',
|
||||
height : '100%',
|
||||
border : 'none',
|
||||
resize : 'none',
|
||||
outline : 'none'
|
||||
} ) ;
|
||||
eTargetElement.appendChild( eTextarea ) ;
|
||||
|
||||
eTextarea.value = html ;
|
||||
|
||||
// Fire the "OnLoad" event.
|
||||
FCKTools.RunFunction( this.OnLoad ) ;
|
||||
}
|
||||
}
|
||||
|
||||
// "this" here is FCKEditingArea.Window
|
||||
function FCKEditingArea_CompleteStart()
|
||||
{
|
||||
// On Firefox, the DOM takes a little to become available. So we must wait for it in a loop.
|
||||
if ( !this.document.body )
|
||||
{
|
||||
this.setTimeout( FCKEditingArea_CompleteStart, 50 ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
var oEditorArea = this._FCKEditingArea ;
|
||||
|
||||
// Save this reference to be re-used later.
|
||||
oEditorArea.Document = oEditorArea.Window.document ;
|
||||
|
||||
oEditorArea.MakeEditable() ;
|
||||
|
||||
// Fire the "OnLoad" event.
|
||||
FCKTools.RunFunction( oEditorArea.OnLoad ) ;
|
||||
}
|
||||
|
||||
FCKEditingArea.prototype.MakeEditable = function()
|
||||
{
|
||||
var oDoc = this.Document ;
|
||||
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
{
|
||||
// Kludge for #141 and #523
|
||||
oDoc.body.disabled = true ;
|
||||
oDoc.body.contentEditable = true ;
|
||||
oDoc.body.removeAttribute( "disabled" ) ;
|
||||
|
||||
/* The following commands don't throw errors, but have no effect.
|
||||
oDoc.execCommand( 'AutoDetect', false, false ) ;
|
||||
oDoc.execCommand( 'KeepSelection', false, true ) ;
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// Disable Firefox 2 Spell Checker.
|
||||
oDoc.body.spellcheck = ( this.FFSpellChecker !== false ) ;
|
||||
|
||||
if ( this._BodyHTML )
|
||||
{
|
||||
oDoc.body.innerHTML = this._BodyHTML ;
|
||||
oDoc.body.offsetLeft ; // Don't remove, this is a hack to fix Opera 9.50, see #2264.
|
||||
this._BodyHTML = null ;
|
||||
}
|
||||
|
||||
oDoc.designMode = 'on' ;
|
||||
|
||||
// Tell Gecko (Firefox 1.5+) to enable or not live resizing of objects (by Alfonso Martinez)
|
||||
oDoc.execCommand( 'enableObjectResizing', false, !FCKConfig.DisableObjectResizing ) ;
|
||||
|
||||
// Disable the standard table editing features of Firefox.
|
||||
oDoc.execCommand( 'enableInlineTableEditing', false, !FCKConfig.DisableFFTableHandles ) ;
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// In Firefox if the iframe is initially hidden it can't be set to designMode and it raises an exception
|
||||
// So we set up a DOM Mutation event Listener on the HTML, as it will raise several events when the document is visible again
|
||||
FCKTools.AddEventListener( this.Window.frameElement, 'DOMAttrModified', FCKEditingArea_Document_AttributeNodeModified ) ;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// This function processes the notifications of the DOM Mutation event on the document
|
||||
// We use it to know that the document will be ready to be editable again (or we hope so)
|
||||
function FCKEditingArea_Document_AttributeNodeModified( evt )
|
||||
{
|
||||
var editingArea = evt.currentTarget.contentWindow._FCKEditingArea ;
|
||||
|
||||
// We want to run our function after the events no longer fire, so we can know that it's a stable situation
|
||||
if ( editingArea._timer )
|
||||
window.clearTimeout( editingArea._timer ) ;
|
||||
|
||||
editingArea._timer = FCKTools.SetTimeout( FCKEditingArea_MakeEditableByMutation, 1000, editingArea ) ;
|
||||
}
|
||||
|
||||
// This function ideally should be called after the document is visible, it does clean up of the
|
||||
// mutation tracking and tries again to make the area editable.
|
||||
function FCKEditingArea_MakeEditableByMutation()
|
||||
{
|
||||
// Clean up
|
||||
delete this._timer ;
|
||||
// Now we don't want to keep on getting this event
|
||||
FCKTools.RemoveEventListener( this.Window.frameElement, 'DOMAttrModified', FCKEditingArea_Document_AttributeNodeModified ) ;
|
||||
// Let's try now to set the editing area editable
|
||||
// If it fails it will set up the Mutation Listener again automatically
|
||||
this.MakeEditable() ;
|
||||
}
|
||||
|
||||
FCKEditingArea.prototype.Focus = function()
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( this.Mode == FCK_EDITMODE_WYSIWYG )
|
||||
{
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
this._FocusIE() ;
|
||||
else
|
||||
this.Window.focus() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
var oDoc = FCKTools.GetElementDocument( this.Textarea ) ;
|
||||
if ( (!oDoc.hasFocus || oDoc.hasFocus() ) && oDoc.activeElement == this.Textarea )
|
||||
return ;
|
||||
|
||||
this.Textarea.focus() ;
|
||||
}
|
||||
}
|
||||
catch(e) {}
|
||||
}
|
||||
|
||||
FCKEditingArea.prototype._FocusIE = function()
|
||||
{
|
||||
// In IE it can happen that the document is in theory focused but the
|
||||
// active element is outside of it.
|
||||
this.Document.body.setActive() ;
|
||||
|
||||
this.Window.focus() ;
|
||||
|
||||
// Kludge for #141... yet more code to workaround IE bugs
|
||||
var range = this.Document.selection.createRange() ;
|
||||
|
||||
var parentNode = range.parentElement() ;
|
||||
var parentTag = parentNode.nodeName.toLowerCase() ;
|
||||
|
||||
// Only apply the fix when in a block, and the block is empty.
|
||||
if ( parentNode.childNodes.length > 0 ||
|
||||
!( FCKListsLib.BlockElements[parentTag] ||
|
||||
FCKListsLib.NonEmptyBlockElements[parentTag] ) )
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
// Force the selection to happen, in this way we guarantee the focus will
|
||||
// be there.
|
||||
range = new FCKDomRange( this.Window ) ;
|
||||
range.MoveToElementEditStart( parentNode ) ;
|
||||
range.Select() ;
|
||||
}
|
||||
|
||||
function FCKEditingArea_Cleanup()
|
||||
{
|
||||
if ( this.Document )
|
||||
this.Document.body.innerHTML = "" ;
|
||||
this.TargetElement = null ;
|
||||
this.IFrame = null ;
|
||||
this.Document = null ;
|
||||
this.Textarea = null ;
|
||||
|
||||
if ( this.Window )
|
||||
{
|
||||
this.Window._FCKEditingArea = null ;
|
||||
this.Window = null ;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Manages the DOM ascensors element list of a specific DOM node
|
||||
* (limited to body, inclusive).
|
||||
*/
|
||||
|
||||
var FCKElementPath = function( lastNode )
|
||||
{
|
||||
var eBlock = null ;
|
||||
var eBlockLimit = null ;
|
||||
|
||||
var aElements = new Array() ;
|
||||
|
||||
var e = lastNode ;
|
||||
while ( e )
|
||||
{
|
||||
if ( e.nodeType == 1 )
|
||||
{
|
||||
if ( !this.LastElement )
|
||||
this.LastElement = e ;
|
||||
|
||||
var sElementName = e.nodeName.toLowerCase() ;
|
||||
if ( FCKBrowserInfo.IsIE && e.scopeName != 'HTML' )
|
||||
sElementName = e.scopeName.toLowerCase() + ':' + sElementName ;
|
||||
|
||||
if ( !eBlockLimit )
|
||||
{
|
||||
if ( !eBlock && FCKListsLib.PathBlockElements[ sElementName ] != null )
|
||||
eBlock = e ;
|
||||
|
||||
if ( FCKListsLib.PathBlockLimitElements[ sElementName ] != null )
|
||||
{
|
||||
// DIV is considered the Block, if no block is available (#525)
|
||||
// and if it doesn't contain other blocks.
|
||||
if ( !eBlock && sElementName == 'div' && !FCKElementPath._CheckHasBlock( e ) )
|
||||
eBlock = e ;
|
||||
else
|
||||
eBlockLimit = e ;
|
||||
}
|
||||
}
|
||||
|
||||
aElements.push( e ) ;
|
||||
|
||||
if ( sElementName == 'body' )
|
||||
break ;
|
||||
}
|
||||
e = e.parentNode ;
|
||||
}
|
||||
|
||||
this.Block = eBlock ;
|
||||
this.BlockLimit = eBlockLimit ;
|
||||
this.Elements = aElements ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an element contains any block element.
|
||||
*/
|
||||
FCKElementPath._CheckHasBlock = function( element )
|
||||
{
|
||||
var childNodes = element.childNodes ;
|
||||
|
||||
for ( var i = 0, count = childNodes.length ; i < count ; i++ )
|
||||
{
|
||||
var child = childNodes[i] ;
|
||||
|
||||
if ( child.nodeType == 1 && FCKListsLib.BlockElements[ child.nodeName.toLowerCase() ] )
|
||||
return true ;
|
||||
}
|
||||
|
||||
return false ;
|
||||
}
|
||||
@@ -0,0 +1,688 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Controls the [Enter] keystroke behavior in a document.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
* @targetDocument : the target document.
|
||||
* @enterMode : the behavior for the <Enter> keystroke.
|
||||
* May be "p", "div", "br". Default is "p".
|
||||
* @shiftEnterMode : the behavior for the <Shift>+<Enter> keystroke.
|
||||
* May be "p", "div", "br". Defaults to "br".
|
||||
*/
|
||||
var FCKEnterKey = function( targetWindow, enterMode, shiftEnterMode, tabSpaces )
|
||||
{
|
||||
this.Window = targetWindow ;
|
||||
this.EnterMode = enterMode || 'p' ;
|
||||
this.ShiftEnterMode = shiftEnterMode || 'br' ;
|
||||
|
||||
// Setup the Keystroke Handler.
|
||||
var oKeystrokeHandler = new FCKKeystrokeHandler( false ) ;
|
||||
oKeystrokeHandler._EnterKey = this ;
|
||||
oKeystrokeHandler.OnKeystroke = FCKEnterKey_OnKeystroke ;
|
||||
|
||||
oKeystrokeHandler.SetKeystrokes( [
|
||||
[ 13 , 'Enter' ],
|
||||
[ SHIFT + 13, 'ShiftEnter' ],
|
||||
[ 8 , 'Backspace' ],
|
||||
[ CTRL + 8 , 'CtrlBackspace' ],
|
||||
[ 46 , 'Delete' ]
|
||||
] ) ;
|
||||
|
||||
this.TabText = '' ;
|
||||
|
||||
// Safari by default inserts 4 spaces on TAB, while others make the editor
|
||||
// loose focus. So, we need to handle it here to not include those spaces.
|
||||
if ( tabSpaces > 0 || FCKBrowserInfo.IsSafari )
|
||||
{
|
||||
while ( tabSpaces-- )
|
||||
this.TabText += '\xa0' ;
|
||||
|
||||
oKeystrokeHandler.SetKeystrokes( [ 9, 'Tab' ] );
|
||||
}
|
||||
|
||||
oKeystrokeHandler.AttachToElement( targetWindow.document ) ;
|
||||
}
|
||||
|
||||
|
||||
function FCKEnterKey_OnKeystroke( keyCombination, keystrokeValue )
|
||||
{
|
||||
var oEnterKey = this._EnterKey ;
|
||||
|
||||
try
|
||||
{
|
||||
switch ( keystrokeValue )
|
||||
{
|
||||
case 'Enter' :
|
||||
return oEnterKey.DoEnter() ;
|
||||
break ;
|
||||
case 'ShiftEnter' :
|
||||
return oEnterKey.DoShiftEnter() ;
|
||||
break ;
|
||||
case 'Backspace' :
|
||||
return oEnterKey.DoBackspace() ;
|
||||
break ;
|
||||
case 'Delete' :
|
||||
return oEnterKey.DoDelete() ;
|
||||
break ;
|
||||
case 'Tab' :
|
||||
return oEnterKey.DoTab() ;
|
||||
break ;
|
||||
case 'CtrlBackspace' :
|
||||
return oEnterKey.DoCtrlBackspace() ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// If for any reason we are not able to handle it, go
|
||||
// ahead with the browser default behavior.
|
||||
}
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes the <Enter> key behavior.
|
||||
*/
|
||||
FCKEnterKey.prototype.DoEnter = function( mode, hasShift )
|
||||
{
|
||||
// Save an undo snapshot before doing anything
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
this._HasShift = ( hasShift === true ) ;
|
||||
|
||||
var parentElement = FCKSelection.GetParentElement() ;
|
||||
var parentPath = new FCKElementPath( parentElement ) ;
|
||||
var sMode = mode || this.EnterMode ;
|
||||
|
||||
if ( sMode == 'br' || parentPath.Block && parentPath.Block.tagName.toLowerCase() == 'pre' )
|
||||
return this._ExecuteEnterBr() ;
|
||||
else
|
||||
return this._ExecuteEnterBlock( sMode ) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes the <Shift>+<Enter> key behavior.
|
||||
*/
|
||||
FCKEnterKey.prototype.DoShiftEnter = function()
|
||||
{
|
||||
return this.DoEnter( this.ShiftEnterMode, true ) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes the <Backspace> key behavior.
|
||||
*/
|
||||
FCKEnterKey.prototype.DoBackspace = function()
|
||||
{
|
||||
var bCustom = false ;
|
||||
|
||||
// Get the current selection.
|
||||
var oRange = new FCKDomRange( this.Window ) ;
|
||||
oRange.MoveToSelection() ;
|
||||
|
||||
// Kludge for #247
|
||||
if ( FCKBrowserInfo.IsIE && this._CheckIsAllContentsIncluded( oRange, this.Window.document.body ) )
|
||||
{
|
||||
this._FixIESelectAllBug( oRange ) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
var isCollapsed = oRange.CheckIsCollapsed() ;
|
||||
|
||||
if ( !isCollapsed )
|
||||
{
|
||||
// Bug #327, Backspace with an img selection would activate the default action in IE.
|
||||
// Let's override that with our logic here.
|
||||
if ( FCKBrowserInfo.IsIE && this.Window.document.selection.type.toLowerCase() == "control" )
|
||||
{
|
||||
var controls = this.Window.document.selection.createRange() ;
|
||||
for ( var i = controls.length - 1 ; i >= 0 ; i-- )
|
||||
{
|
||||
var el = controls.item( i ) ;
|
||||
el.parentNode.removeChild( el ) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
// On IE, it is better for us handle the deletion if the caret is preceeded
|
||||
// by a <br> (#1383).
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
{
|
||||
var previousElement = FCKDomTools.GetPreviousSourceElement( oRange.StartNode, true ) ;
|
||||
|
||||
if ( previousElement && previousElement.nodeName.toLowerCase() == 'br' )
|
||||
{
|
||||
// Create a range that starts after the <br> and ends at the
|
||||
// current range position.
|
||||
var testRange = oRange.Clone() ;
|
||||
testRange.SetStart( previousElement, 4 ) ;
|
||||
|
||||
// If that range is empty, we can proceed cleaning that <br> manually.
|
||||
if ( testRange.CheckIsEmpty() )
|
||||
{
|
||||
previousElement.parentNode.removeChild( previousElement ) ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var oStartBlock = oRange.StartBlock ;
|
||||
var oEndBlock = oRange.EndBlock ;
|
||||
|
||||
// The selection boundaries must be in the same "block limit" element
|
||||
if ( oRange.StartBlockLimit == oRange.EndBlockLimit && oStartBlock && oEndBlock )
|
||||
{
|
||||
if ( !isCollapsed )
|
||||
{
|
||||
var bEndOfBlock = oRange.CheckEndOfBlock() ;
|
||||
|
||||
oRange.DeleteContents() ;
|
||||
|
||||
if ( oStartBlock != oEndBlock )
|
||||
{
|
||||
oRange.SetStart(oEndBlock,1) ;
|
||||
oRange.SetEnd(oEndBlock,1) ;
|
||||
|
||||
// if ( bEndOfBlock )
|
||||
// oEndBlock.parentNode.removeChild( oEndBlock ) ;
|
||||
}
|
||||
|
||||
oRange.Select() ;
|
||||
|
||||
bCustom = ( oStartBlock == oEndBlock ) ;
|
||||
}
|
||||
|
||||
if ( oRange.CheckStartOfBlock() )
|
||||
{
|
||||
var oCurrentBlock = oRange.StartBlock ;
|
||||
|
||||
var ePrevious = FCKDomTools.GetPreviousSourceElement( oCurrentBlock, true, [ 'BODY', oRange.StartBlockLimit.nodeName ], ['UL','OL'] ) ;
|
||||
|
||||
bCustom = this._ExecuteBackspace( oRange, ePrevious, oCurrentBlock ) ;
|
||||
}
|
||||
else if ( FCKBrowserInfo.IsGeckoLike )
|
||||
{
|
||||
// Firefox and Opera (#1095) loose the selection when executing
|
||||
// CheckStartOfBlock, so we must reselect.
|
||||
oRange.Select() ;
|
||||
}
|
||||
}
|
||||
|
||||
oRange.Release() ;
|
||||
return bCustom ;
|
||||
}
|
||||
|
||||
FCKEnterKey.prototype.DoCtrlBackspace = function()
|
||||
{
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
var oRange = new FCKDomRange( this.Window ) ;
|
||||
oRange.MoveToSelection() ;
|
||||
if ( FCKBrowserInfo.IsIE && this._CheckIsAllContentsIncluded( oRange, this.Window.document.body ) )
|
||||
{
|
||||
this._FixIESelectAllBug( oRange ) ;
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
FCKEnterKey.prototype._ExecuteBackspace = function( range, previous, currentBlock )
|
||||
{
|
||||
var bCustom = false ;
|
||||
|
||||
// We could be in a nested LI.
|
||||
if ( !previous && currentBlock && currentBlock.nodeName.IEquals( 'LI' ) && currentBlock.parentNode.parentNode.nodeName.IEquals( 'LI' ) )
|
||||
{
|
||||
this._OutdentWithSelection( currentBlock, range ) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
if ( previous && previous.nodeName.IEquals( 'LI' ) )
|
||||
{
|
||||
var oNestedList = FCKDomTools.GetLastChild( previous, ['UL','OL'] ) ;
|
||||
|
||||
while ( oNestedList )
|
||||
{
|
||||
previous = FCKDomTools.GetLastChild( oNestedList, 'LI' ) ;
|
||||
oNestedList = FCKDomTools.GetLastChild( previous, ['UL','OL'] ) ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( previous && currentBlock )
|
||||
{
|
||||
// If we are in a LI, and the previous block is not an LI, we must outdent it.
|
||||
if ( currentBlock.nodeName.IEquals( 'LI' ) && !previous.nodeName.IEquals( 'LI' ) )
|
||||
{
|
||||
this._OutdentWithSelection( currentBlock, range ) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Take a reference to the parent for post processing cleanup.
|
||||
var oCurrentParent = currentBlock.parentNode ;
|
||||
|
||||
var sPreviousName = previous.nodeName.toLowerCase() ;
|
||||
if ( FCKListsLib.EmptyElements[ sPreviousName ] != null || sPreviousName == 'table' )
|
||||
{
|
||||
FCKDomTools.RemoveNode( previous ) ;
|
||||
bCustom = true ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove the current block.
|
||||
FCKDomTools.RemoveNode( currentBlock ) ;
|
||||
|
||||
// Remove any empty tag left by the block removal.
|
||||
while ( oCurrentParent.innerHTML.Trim().length == 0 )
|
||||
{
|
||||
var oParent = oCurrentParent.parentNode ;
|
||||
oParent.removeChild( oCurrentParent ) ;
|
||||
oCurrentParent = oParent ;
|
||||
}
|
||||
|
||||
// Cleanup the previous and the current elements.
|
||||
FCKDomTools.LTrimNode( currentBlock ) ;
|
||||
FCKDomTools.RTrimNode( previous ) ;
|
||||
|
||||
// Append a space to the previous.
|
||||
// Maybe it is not always desirable...
|
||||
// previous.appendChild( this.Window.document.createTextNode( ' ' ) ) ;
|
||||
|
||||
// Set the range to the end of the previous element and bookmark it.
|
||||
range.SetStart( previous, 2, true ) ;
|
||||
range.Collapse( true ) ;
|
||||
var oBookmark = range.CreateBookmark( true ) ;
|
||||
|
||||
// Move the contents of the block to the previous element and delete it.
|
||||
// But for some block types (e.g. table), moving the children to the previous block makes no sense.
|
||||
// So a check is needed. (See #1081)
|
||||
if ( ! currentBlock.tagName.IEquals( [ 'TABLE' ] ) )
|
||||
FCKDomTools.MoveChildren( currentBlock, previous ) ;
|
||||
|
||||
// Place the selection at the bookmark.
|
||||
range.SelectBookmark( oBookmark ) ;
|
||||
|
||||
bCustom = true ;
|
||||
}
|
||||
}
|
||||
|
||||
return bCustom ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes the <Delete> key behavior.
|
||||
*/
|
||||
FCKEnterKey.prototype.DoDelete = function()
|
||||
{
|
||||
// Save an undo snapshot before doing anything
|
||||
// This is to conform with the behavior seen in MS Word
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
// The <Delete> has the same effect as the <Backspace>, so we have the same
|
||||
// results if we just move to the next block and apply the same <Backspace> logic.
|
||||
|
||||
var bCustom = false ;
|
||||
|
||||
// Get the current selection.
|
||||
var oRange = new FCKDomRange( this.Window ) ;
|
||||
oRange.MoveToSelection() ;
|
||||
|
||||
// Kludge for #247
|
||||
if ( FCKBrowserInfo.IsIE && this._CheckIsAllContentsIncluded( oRange, this.Window.document.body ) )
|
||||
{
|
||||
this._FixIESelectAllBug( oRange ) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// There is just one special case for collapsed selections at the end of a block.
|
||||
if ( oRange.CheckIsCollapsed() && oRange.CheckEndOfBlock( FCKBrowserInfo.IsGeckoLike ) )
|
||||
{
|
||||
var oCurrentBlock = oRange.StartBlock ;
|
||||
var eCurrentCell = FCKTools.GetElementAscensor( oCurrentBlock, 'td' );
|
||||
|
||||
var eNext = FCKDomTools.GetNextSourceElement( oCurrentBlock, true, [ oRange.StartBlockLimit.nodeName ],
|
||||
['UL','OL','TR'], true ) ;
|
||||
|
||||
// Bug #1323 : if we're in a table cell, and the next node belongs to a different cell, then don't
|
||||
// delete anything.
|
||||
if ( eCurrentCell )
|
||||
{
|
||||
var eNextCell = FCKTools.GetElementAscensor( eNext, 'td' );
|
||||
if ( eNextCell != eCurrentCell )
|
||||
return true ;
|
||||
}
|
||||
|
||||
bCustom = this._ExecuteBackspace( oRange, oCurrentBlock, eNext ) ;
|
||||
}
|
||||
|
||||
oRange.Release() ;
|
||||
return bCustom ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes the <Tab> key behavior.
|
||||
*/
|
||||
FCKEnterKey.prototype.DoTab = function()
|
||||
{
|
||||
var oRange = new FCKDomRange( this.Window );
|
||||
oRange.MoveToSelection() ;
|
||||
|
||||
// If the user pressed <tab> inside a table, we should give him the default behavior ( moving between cells )
|
||||
// instead of giving him more non-breaking spaces. (Bug #973)
|
||||
var node = oRange._Range.startContainer ;
|
||||
while ( node )
|
||||
{
|
||||
if ( node.nodeType == 1 )
|
||||
{
|
||||
var tagName = node.tagName.toLowerCase() ;
|
||||
if ( tagName == "tr" || tagName == "td" || tagName == "th" || tagName == "tbody" || tagName == "table" )
|
||||
return false ;
|
||||
else
|
||||
break ;
|
||||
}
|
||||
node = node.parentNode ;
|
||||
}
|
||||
|
||||
if ( this.TabText )
|
||||
{
|
||||
oRange.DeleteContents() ;
|
||||
oRange.InsertNode( this.Window.document.createTextNode( this.TabText ) ) ;
|
||||
oRange.Collapse( false ) ;
|
||||
oRange.Select() ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
FCKEnterKey.prototype._ExecuteEnterBlock = function( blockTag, range )
|
||||
{
|
||||
// Get the current selection.
|
||||
var oRange = range || new FCKDomRange( this.Window ) ;
|
||||
|
||||
var oSplitInfo = oRange.SplitBlock( blockTag ) ;
|
||||
|
||||
if ( oSplitInfo )
|
||||
{
|
||||
// Get the current blocks.
|
||||
var ePreviousBlock = oSplitInfo.PreviousBlock ;
|
||||
var eNextBlock = oSplitInfo.NextBlock ;
|
||||
|
||||
var bIsStartOfBlock = oSplitInfo.WasStartOfBlock ;
|
||||
var bIsEndOfBlock = oSplitInfo.WasEndOfBlock ;
|
||||
|
||||
// If there is one block under a list item, modify the split so that the list item gets split as well. (Bug #1647)
|
||||
if ( eNextBlock )
|
||||
{
|
||||
if ( eNextBlock.parentNode.nodeName.IEquals( 'li' ) )
|
||||
{
|
||||
FCKDomTools.BreakParent( eNextBlock, eNextBlock.parentNode ) ;
|
||||
FCKDomTools.MoveNode( eNextBlock, eNextBlock.nextSibling, true ) ;
|
||||
}
|
||||
}
|
||||
else if ( ePreviousBlock && ePreviousBlock.parentNode.nodeName.IEquals( 'li' ) )
|
||||
{
|
||||
FCKDomTools.BreakParent( ePreviousBlock, ePreviousBlock.parentNode ) ;
|
||||
oRange.MoveToElementEditStart( ePreviousBlock.nextSibling );
|
||||
FCKDomTools.MoveNode( ePreviousBlock, ePreviousBlock.previousSibling ) ;
|
||||
}
|
||||
|
||||
// If we have both the previous and next blocks, it means that the
|
||||
// boundaries were on separated blocks, or none of them where on the
|
||||
// block limits (start/end).
|
||||
if ( !bIsStartOfBlock && !bIsEndOfBlock )
|
||||
{
|
||||
// If the next block is an <li> with another list tree as the first child
|
||||
// We'll need to append a placeholder or the list item wouldn't be editable. (Bug #1420)
|
||||
if ( eNextBlock.nodeName.IEquals( 'li' ) && eNextBlock.firstChild
|
||||
&& eNextBlock.firstChild.nodeName.IEquals( ['ul', 'ol'] ) )
|
||||
eNextBlock.insertBefore( FCKTools.GetElementDocument( eNextBlock ).createTextNode( '\xa0' ), eNextBlock.firstChild ) ;
|
||||
// Move the selection to the end block.
|
||||
if ( eNextBlock )
|
||||
oRange.MoveToElementEditStart( eNextBlock ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bIsStartOfBlock && bIsEndOfBlock && ePreviousBlock.tagName.toUpperCase() == 'LI' )
|
||||
{
|
||||
oRange.MoveToElementStart( ePreviousBlock ) ;
|
||||
this._OutdentWithSelection( ePreviousBlock, oRange ) ;
|
||||
oRange.Release() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
var eNewBlock ;
|
||||
|
||||
if ( ePreviousBlock )
|
||||
{
|
||||
var sPreviousBlockTag = ePreviousBlock.tagName.toUpperCase() ;
|
||||
|
||||
// If is a header tag, or we are in a Shift+Enter (#77),
|
||||
// create a new block element (later in the code).
|
||||
if ( !this._HasShift && !(/^H[1-6]$/).test( sPreviousBlockTag ) )
|
||||
{
|
||||
// Otherwise, duplicate the previous block.
|
||||
eNewBlock = FCKDomTools.CloneElement( ePreviousBlock ) ;
|
||||
}
|
||||
}
|
||||
else if ( eNextBlock )
|
||||
eNewBlock = FCKDomTools.CloneElement( eNextBlock ) ;
|
||||
|
||||
if ( !eNewBlock )
|
||||
eNewBlock = this.Window.document.createElement( blockTag ) ;
|
||||
|
||||
// Recreate the inline elements tree, which was available
|
||||
// before the hitting enter, so the same styles will be
|
||||
// available in the new block.
|
||||
var elementPath = oSplitInfo.ElementPath ;
|
||||
if ( elementPath )
|
||||
{
|
||||
for ( var i = 0, len = elementPath.Elements.length ; i < len ; i++ )
|
||||
{
|
||||
var element = elementPath.Elements[i] ;
|
||||
|
||||
if ( element == elementPath.Block || element == elementPath.BlockLimit )
|
||||
break ;
|
||||
|
||||
if ( FCKListsLib.InlineChildReqElements[ element.nodeName.toLowerCase() ] )
|
||||
{
|
||||
element = FCKDomTools.CloneElement( element ) ;
|
||||
FCKDomTools.MoveChildren( eNewBlock, element ) ;
|
||||
eNewBlock.appendChild( element ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( FCKBrowserInfo.IsGeckoLike )
|
||||
FCKTools.AppendBogusBr( eNewBlock ) ;
|
||||
|
||||
oRange.InsertNode( eNewBlock ) ;
|
||||
|
||||
// This is tricky, but to make the new block visible correctly
|
||||
// we must select it.
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
{
|
||||
// Move the selection to the new block.
|
||||
oRange.MoveToElementEditStart( eNewBlock ) ;
|
||||
oRange.Select() ;
|
||||
}
|
||||
|
||||
// Move the selection to the new block.
|
||||
oRange.MoveToElementEditStart( bIsStartOfBlock && !bIsEndOfBlock ? eNextBlock : eNewBlock ) ;
|
||||
}
|
||||
|
||||
if ( FCKBrowserInfo.IsGeckoLike )
|
||||
FCKDomTools.ScrollIntoView( eNextBlock || eNewBlock, false ) ;
|
||||
|
||||
oRange.Select() ;
|
||||
}
|
||||
|
||||
// Release the resources used by the range.
|
||||
oRange.Release() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
FCKEnterKey.prototype._ExecuteEnterBr = function( blockTag )
|
||||
{
|
||||
// Get the current selection.
|
||||
var oRange = new FCKDomRange( this.Window ) ;
|
||||
oRange.MoveToSelection() ;
|
||||
|
||||
// The selection boundaries must be in the same "block limit" element.
|
||||
if ( oRange.StartBlockLimit == oRange.EndBlockLimit )
|
||||
{
|
||||
oRange.DeleteContents() ;
|
||||
|
||||
// Get the new selection (it is collapsed at this point).
|
||||
oRange.MoveToSelection() ;
|
||||
|
||||
var bIsStartOfBlock = oRange.CheckStartOfBlock() ;
|
||||
var bIsEndOfBlock = oRange.CheckEndOfBlock() ;
|
||||
|
||||
var sStartBlockTag = oRange.StartBlock ? oRange.StartBlock.tagName.toUpperCase() : '' ;
|
||||
|
||||
var bHasShift = this._HasShift ;
|
||||
var bIsPre = false ;
|
||||
|
||||
if ( !bHasShift && sStartBlockTag == 'LI' )
|
||||
return this._ExecuteEnterBlock( null, oRange ) ;
|
||||
|
||||
// If we are at the end of a header block.
|
||||
if ( !bHasShift && bIsEndOfBlock && (/^H[1-6]$/).test( sStartBlockTag ) )
|
||||
{
|
||||
// Insert a BR after the current paragraph.
|
||||
FCKDomTools.InsertAfterNode( oRange.StartBlock, this.Window.document.createElement( 'br' ) ) ;
|
||||
|
||||
// The space is required by Gecko only to make the cursor blink.
|
||||
if ( FCKBrowserInfo.IsGecko )
|
||||
FCKDomTools.InsertAfterNode( oRange.StartBlock, this.Window.document.createTextNode( '' ) ) ;
|
||||
|
||||
// IE and Gecko have different behaviors regarding the position.
|
||||
oRange.SetStart( oRange.StartBlock.nextSibling, FCKBrowserInfo.IsIE ? 3 : 1 ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
var eLineBreak ;
|
||||
bIsPre = sStartBlockTag.IEquals( 'pre' ) ;
|
||||
if ( bIsPre )
|
||||
eLineBreak = this.Window.document.createTextNode( FCKBrowserInfo.IsIE ? '\r' : '\n' ) ;
|
||||
else
|
||||
eLineBreak = this.Window.document.createElement( 'br' ) ;
|
||||
|
||||
oRange.InsertNode( eLineBreak ) ;
|
||||
|
||||
// The space is required by Gecko only to make the cursor blink.
|
||||
if ( FCKBrowserInfo.IsGecko )
|
||||
FCKDomTools.InsertAfterNode( eLineBreak, this.Window.document.createTextNode( '' ) ) ;
|
||||
|
||||
// If we are at the end of a block, we must be sure the bogus node is available in that block.
|
||||
if ( bIsEndOfBlock && FCKBrowserInfo.IsGeckoLike )
|
||||
FCKTools.AppendBogusBr( eLineBreak.parentNode ) ;
|
||||
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
oRange.SetStart( eLineBreak, 4 ) ;
|
||||
else
|
||||
oRange.SetStart( eLineBreak.nextSibling, 1 ) ;
|
||||
|
||||
if ( ! FCKBrowserInfo.IsIE )
|
||||
{
|
||||
var dummy = null ;
|
||||
if ( FCKBrowserInfo.IsOpera )
|
||||
dummy = this.Window.document.createElement( 'span' ) ;
|
||||
else
|
||||
dummy = this.Window.document.createElement( 'br' ) ;
|
||||
|
||||
eLineBreak.parentNode.insertBefore( dummy, eLineBreak.nextSibling ) ;
|
||||
|
||||
FCKDomTools.ScrollIntoView( dummy, false ) ;
|
||||
|
||||
dummy.parentNode.removeChild( dummy ) ;
|
||||
}
|
||||
}
|
||||
|
||||
// This collapse guarantees the cursor will be blinking.
|
||||
oRange.Collapse( true ) ;
|
||||
|
||||
oRange.Select( bIsPre ) ;
|
||||
}
|
||||
|
||||
// Release the resources used by the range.
|
||||
oRange.Release() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Outdents a LI, maintaining the selection defined on a range.
|
||||
FCKEnterKey.prototype._OutdentWithSelection = function( li, range )
|
||||
{
|
||||
var oBookmark = range.CreateBookmark() ;
|
||||
|
||||
FCKListHandler.OutdentListItem( li ) ;
|
||||
|
||||
range.MoveToBookmark( oBookmark ) ;
|
||||
range.Select() ;
|
||||
}
|
||||
|
||||
// Is all the contents under a node included by a range?
|
||||
FCKEnterKey.prototype._CheckIsAllContentsIncluded = function( range, node )
|
||||
{
|
||||
var startOk = false ;
|
||||
var endOk = false ;
|
||||
|
||||
/*
|
||||
FCKDebug.Output( 'sc='+range.StartContainer.nodeName+
|
||||
',so='+range._Range.startOffset+
|
||||
',ec='+range.EndContainer.nodeName+
|
||||
',eo='+range._Range.endOffset ) ;
|
||||
*/
|
||||
if ( range.StartContainer == node || range.StartContainer == node.firstChild )
|
||||
startOk = ( range._Range.startOffset == 0 ) ;
|
||||
|
||||
if ( range.EndContainer == node || range.EndContainer == node.lastChild )
|
||||
{
|
||||
var nodeLength = range.EndContainer.nodeType == 3 ? range.EndContainer.length : range.EndContainer.childNodes.length ;
|
||||
endOk = ( range._Range.endOffset == nodeLength ) ;
|
||||
}
|
||||
|
||||
return startOk && endOk ;
|
||||
}
|
||||
|
||||
// Kludge for #247
|
||||
FCKEnterKey.prototype._FixIESelectAllBug = function( range )
|
||||
{
|
||||
var doc = this.Window.document ;
|
||||
doc.body.innerHTML = '' ;
|
||||
var editBlock ;
|
||||
if ( FCKConfig.EnterMode.IEquals( ['div', 'p'] ) )
|
||||
{
|
||||
editBlock = doc.createElement( FCKConfig.EnterMode ) ;
|
||||
doc.body.appendChild( editBlock ) ;
|
||||
}
|
||||
else
|
||||
editBlock = doc.body ;
|
||||
|
||||
range.MoveToNodeContents( editBlock ) ;
|
||||
range.Collapse( true ) ;
|
||||
range.Select() ;
|
||||
range.Release() ;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKEvents Class: used to handle events is a advanced way.
|
||||
*/
|
||||
|
||||
var FCKEvents = function( eventsOwner )
|
||||
{
|
||||
this.Owner = eventsOwner ;
|
||||
this._RegisteredEvents = new Object() ;
|
||||
}
|
||||
|
||||
FCKEvents.prototype.AttachEvent = function( eventName, functionPointer )
|
||||
{
|
||||
var aTargets ;
|
||||
|
||||
if ( !( aTargets = this._RegisteredEvents[ eventName ] ) )
|
||||
this._RegisteredEvents[ eventName ] = [ functionPointer ] ;
|
||||
else
|
||||
{
|
||||
// Check that the event handler isn't already registered with the same listener
|
||||
// It doesn't detect function pointers belonging to an object (at least in Gecko)
|
||||
if ( aTargets.IndexOf( functionPointer ) == -1 )
|
||||
aTargets.push( functionPointer ) ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKEvents.prototype.FireEvent = function( eventName, params )
|
||||
{
|
||||
var bReturnValue = true ;
|
||||
|
||||
var oCalls = this._RegisteredEvents[ eventName ] ;
|
||||
|
||||
if ( oCalls )
|
||||
{
|
||||
for ( var i = 0 ; i < oCalls.length ; i++ )
|
||||
{
|
||||
try
|
||||
{
|
||||
bReturnValue = ( oCalls[ i ]( this.Owner, params ) && bReturnValue ) ;
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
// Ignore the following error. It may happen if pointing to a
|
||||
// script not anymore available (#934):
|
||||
// -2146823277 = Can't execute code from a freed script
|
||||
if ( e.number != -2146823277 )
|
||||
throw e ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bReturnValue ;
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* This class can be used to interate through nodes inside a range.
|
||||
*
|
||||
* During interation, the provided range can become invalid, due to document
|
||||
* mutations, so CreateBookmark() used to restore it after processing, if
|
||||
* needed.
|
||||
*/
|
||||
|
||||
var FCKHtmlIterator = function( source )
|
||||
{
|
||||
this._sourceHtml = source ;
|
||||
}
|
||||
FCKHtmlIterator.prototype =
|
||||
{
|
||||
Next : function()
|
||||
{
|
||||
var sourceHtml = this._sourceHtml ;
|
||||
if ( sourceHtml == null )
|
||||
return null ;
|
||||
|
||||
var match = FCKRegexLib.HtmlTag.exec( sourceHtml ) ;
|
||||
var isTag = false ;
|
||||
var value = "" ;
|
||||
if ( match )
|
||||
{
|
||||
if ( match.index > 0 )
|
||||
{
|
||||
value = sourceHtml.substr( 0, match.index ) ;
|
||||
this._sourceHtml = sourceHtml.substr( match.index ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
isTag = true ;
|
||||
value = match[0] ;
|
||||
this._sourceHtml = sourceHtml.substr( match[0].length ) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = sourceHtml ;
|
||||
this._sourceHtml = null ;
|
||||
}
|
||||
return { 'isTag' : isTag, 'value' : value } ;
|
||||
},
|
||||
|
||||
Each : function( func )
|
||||
{
|
||||
var chunk ;
|
||||
while ( ( chunk = this.Next() ) )
|
||||
func( chunk.isTag, chunk.value ) ;
|
||||
}
|
||||
} ;
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* This class can be used to interate through nodes inside a range.
|
||||
*
|
||||
* During interation, the provided range can become invalid, due to document
|
||||
* mutations, so CreateBookmark() used to restore it after processing, if
|
||||
* needed.
|
||||
*/
|
||||
|
||||
var FCKHtmlIterator = function( source )
|
||||
{
|
||||
this._sourceHtml = source ;
|
||||
}
|
||||
FCKHtmlIterator.prototype =
|
||||
{
|
||||
Next : function()
|
||||
{
|
||||
var sourceHtml = this._sourceHtml ;
|
||||
if ( sourceHtml == null )
|
||||
return null ;
|
||||
|
||||
var match = FCKRegexLib.HtmlTag.exec( sourceHtml ) ;
|
||||
var isTag = false ;
|
||||
var value = "" ;
|
||||
if ( match )
|
||||
{
|
||||
if ( match.index > 0 )
|
||||
{
|
||||
value = sourceHtml.substr( 0, match.index ) ;
|
||||
this._sourceHtml = sourceHtml.substr( match.index ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
isTag = true ;
|
||||
value = match[0] ;
|
||||
this._sourceHtml = sourceHtml.substr( match[0].length ) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = sourceHtml ;
|
||||
this._sourceHtml = null ;
|
||||
}
|
||||
return { 'isTag' : isTag, 'value' : value } ;
|
||||
},
|
||||
|
||||
Each : function( func )
|
||||
{
|
||||
var chunk ;
|
||||
while ( ( chunk = this.Next() ) )
|
||||
func( chunk.isTag, chunk.value ) ;
|
||||
}
|
||||
} ;
|
||||
103
_cubecart/CubeCart-4.3.0/admin/includes/rte/editor/_source/classes/fckicon.js
Executable file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKIcon Class: renders an icon from a single image, a strip or even a
|
||||
* spacer.
|
||||
*/
|
||||
|
||||
var FCKIcon = function( iconPathOrStripInfoArray )
|
||||
{
|
||||
var sTypeOf = iconPathOrStripInfoArray ? typeof( iconPathOrStripInfoArray ) : 'undefined' ;
|
||||
switch ( sTypeOf )
|
||||
{
|
||||
case 'number' :
|
||||
this.Path = FCKConfig.SkinPath + 'fck_strip.gif' ;
|
||||
this.Size = 16 ;
|
||||
this.Position = iconPathOrStripInfoArray ;
|
||||
break ;
|
||||
|
||||
case 'undefined' :
|
||||
this.Path = FCK_SPACER_PATH ;
|
||||
break ;
|
||||
|
||||
case 'string' :
|
||||
this.Path = iconPathOrStripInfoArray ;
|
||||
break ;
|
||||
|
||||
default :
|
||||
// It is an array in the format [ StripFilePath, IconSize, IconPosition ]
|
||||
this.Path = iconPathOrStripInfoArray[0] ;
|
||||
this.Size = iconPathOrStripInfoArray[1] ;
|
||||
this.Position = iconPathOrStripInfoArray[2] ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKIcon.prototype.CreateIconElement = function( document )
|
||||
{
|
||||
var eIcon, eIconImage ;
|
||||
|
||||
if ( this.Position ) // It is using an icons strip image.
|
||||
{
|
||||
var sPos = '-' + ( ( this.Position - 1 ) * this.Size ) + 'px' ;
|
||||
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
{
|
||||
// <div class="TB_Button_Image"><img src="strip.gif" style="top:-16px"></div>
|
||||
|
||||
eIcon = document.createElement( 'DIV' ) ;
|
||||
|
||||
eIconImage = eIcon.appendChild( document.createElement( 'IMG' ) ) ;
|
||||
eIconImage.src = this.Path ;
|
||||
eIconImage.style.top = sPos ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// <img class="TB_Button_Image" src="spacer.gif" style="background-position: 0px -16px;background-image: url(strip.gif);">
|
||||
|
||||
eIcon = document.createElement( 'IMG' ) ;
|
||||
eIcon.src = FCK_SPACER_PATH ;
|
||||
eIcon.style.backgroundPosition = '0px ' + sPos ;
|
||||
eIcon.style.backgroundImage = 'url("' + this.Path + '")' ;
|
||||
}
|
||||
}
|
||||
else // It is using a single icon image.
|
||||
{
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
{
|
||||
// IE makes the button 1px higher if using the <img> directly, so we
|
||||
// are changing to the <div> system to clip the image correctly.
|
||||
eIcon = document.createElement( 'DIV' ) ;
|
||||
|
||||
eIconImage = eIcon.appendChild( document.createElement( 'IMG' ) ) ;
|
||||
eIconImage.src = this.Path ? this.Path : FCK_SPACER_PATH ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is not working well with IE. See notes above.
|
||||
// <img class="TB_Button_Image" src="smiley.gif">
|
||||
eIcon = document.createElement( 'IMG' ) ;
|
||||
eIcon.src = this.Path ? this.Path : FCK_SPACER_PATH ;
|
||||
}
|
||||
}
|
||||
|
||||
eIcon.className = 'TB_Button_Image' ;
|
||||
|
||||
return eIcon ;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKIECleanup Class: a generic class used as a tool to remove IE leaks.
|
||||
*/
|
||||
|
||||
var FCKIECleanup = function( attachWindow )
|
||||
{
|
||||
// If the attachWindow already have a cleanup object, just use that one.
|
||||
if ( attachWindow._FCKCleanupObj )
|
||||
this.Items = attachWindow._FCKCleanupObj.Items ;
|
||||
else
|
||||
{
|
||||
this.Items = new Array() ;
|
||||
|
||||
attachWindow._FCKCleanupObj = this ;
|
||||
FCKTools.AddEventListenerEx( attachWindow, 'unload', FCKIECleanup_Cleanup ) ;
|
||||
// attachWindow.attachEvent( 'onunload', FCKIECleanup_Cleanup ) ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKIECleanup.prototype.AddItem = function( dirtyItem, cleanupFunction )
|
||||
{
|
||||
this.Items.push( [ dirtyItem, cleanupFunction ] ) ;
|
||||
}
|
||||
|
||||
function FCKIECleanup_Cleanup()
|
||||
{
|
||||
if ( !this._FCKCleanupObj || ( FCKConfig.MsWebBrowserControlCompat && !window.FCKUnloadFlag ) )
|
||||
return ;
|
||||
|
||||
var aItems = this._FCKCleanupObj.Items ;
|
||||
|
||||
while ( aItems.length > 0 )
|
||||
{
|
||||
|
||||
// It is important to remove from the end to the beginning (pop()),
|
||||
// because of the order things get created in the editor. In the code,
|
||||
// elements in deeper position in the DOM are placed at the end of the
|
||||
// cleanup function, so we must cleanup then first, otherwise IE could
|
||||
// throw some crazy memory errors (IE bug).
|
||||
var oItem = aItems.pop() ;
|
||||
if ( oItem )
|
||||
oItem[1].call( oItem[0] ) ;
|
||||
}
|
||||
|
||||
this._FCKCleanupObj = null ;
|
||||
|
||||
if ( CollectGarbage )
|
||||
CollectGarbage() ;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Preload a list of images, firing an event when complete.
|
||||
*/
|
||||
|
||||
var FCKImagePreloader = function()
|
||||
{
|
||||
this._Images = new Array() ;
|
||||
}
|
||||
|
||||
FCKImagePreloader.prototype =
|
||||
{
|
||||
AddImages : function( images )
|
||||
{
|
||||
if ( typeof( images ) == 'string' )
|
||||
images = images.split( ';' ) ;
|
||||
|
||||
this._Images = this._Images.concat( images ) ;
|
||||
},
|
||||
|
||||
Start : function()
|
||||
{
|
||||
var aImages = this._Images ;
|
||||
this._PreloadCount = aImages.length ;
|
||||
|
||||
for ( var i = 0 ; i < aImages.length ; i++ )
|
||||
{
|
||||
var eImg = document.createElement( 'img' ) ;
|
||||
FCKTools.AddEventListenerEx( eImg, 'load', _FCKImagePreloader_OnImage, this ) ;
|
||||
FCKTools.AddEventListenerEx( eImg, 'error', _FCKImagePreloader_OnImage, this ) ;
|
||||
eImg.src = aImages[i] ;
|
||||
|
||||
_FCKImagePreloader_ImageCache.push( eImg ) ;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// All preloaded images must be placed in a global array, otherwise the preload
|
||||
// magic will not happen.
|
||||
var _FCKImagePreloader_ImageCache = new Array() ;
|
||||
|
||||
function _FCKImagePreloader_OnImage( ev, imagePreloader )
|
||||
{
|
||||
if ( (--imagePreloader._PreloadCount) == 0 && imagePreloader.OnComplete )
|
||||
imagePreloader.OnComplete() ;
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Control keyboard keystroke combinations.
|
||||
*/
|
||||
|
||||
var FCKKeystrokeHandler = function( cancelCtrlDefaults )
|
||||
{
|
||||
this.Keystrokes = new Object() ;
|
||||
this.CancelCtrlDefaults = ( cancelCtrlDefaults !== false ) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Listen to keystroke events in an element or DOM document object.
|
||||
* @target: The element or document to listen to keystroke events.
|
||||
*/
|
||||
FCKKeystrokeHandler.prototype.AttachToElement = function( target )
|
||||
{
|
||||
// For newer browsers, it is enough to listen to the keydown event only.
|
||||
// Some browsers instead, don't cancel key events in the keydown, but in the
|
||||
// keypress. So we must do a longer trip in those cases.
|
||||
FCKTools.AddEventListenerEx( target, 'keydown', _FCKKeystrokeHandler_OnKeyDown, this ) ;
|
||||
if ( FCKBrowserInfo.IsGecko10 || FCKBrowserInfo.IsOpera || ( FCKBrowserInfo.IsGecko && FCKBrowserInfo.IsMac ) )
|
||||
FCKTools.AddEventListenerEx( target, 'keypress', _FCKKeystrokeHandler_OnKeyPress, this ) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets a list of keystrokes. It can receive either a single array or "n"
|
||||
* arguments, each one being an array of 1 or 2 elemenst. The first element
|
||||
* is the keystroke combination, and the second is the value to assign to it.
|
||||
* If the second element is missing, the keystroke definition is removed.
|
||||
*/
|
||||
FCKKeystrokeHandler.prototype.SetKeystrokes = function()
|
||||
{
|
||||
// Look through the arguments.
|
||||
for ( var i = 0 ; i < arguments.length ; i++ )
|
||||
{
|
||||
var keyDef = arguments[i] ;
|
||||
|
||||
// If the configuration for the keystrokes is missing some element or has any extra comma
|
||||
// this item won't be valid, so skip it and keep on processing.
|
||||
if ( !keyDef )
|
||||
continue ;
|
||||
|
||||
if ( typeof( keyDef[0] ) == 'object' ) // It is an array with arrays defining the keystrokes.
|
||||
this.SetKeystrokes.apply( this, keyDef ) ;
|
||||
else
|
||||
{
|
||||
if ( keyDef.length == 1 ) // If it has only one element, remove the keystroke.
|
||||
delete this.Keystrokes[ keyDef[0] ] ;
|
||||
else // Otherwise add it.
|
||||
this.Keystrokes[ keyDef[0] ] = keyDef[1] === true ? true : keyDef ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _FCKKeystrokeHandler_OnKeyDown( ev, keystrokeHandler )
|
||||
{
|
||||
// Get the key code.
|
||||
var keystroke = ev.keyCode || ev.which ;
|
||||
|
||||
// Combine it with the CTRL, SHIFT and ALT states.
|
||||
var keyModifiers = 0 ;
|
||||
|
||||
if ( ev.ctrlKey || ev.metaKey )
|
||||
keyModifiers += CTRL ;
|
||||
|
||||
if ( ev.shiftKey )
|
||||
keyModifiers += SHIFT ;
|
||||
|
||||
if ( ev.altKey )
|
||||
keyModifiers += ALT ;
|
||||
|
||||
var keyCombination = keystroke + keyModifiers ;
|
||||
|
||||
var cancelIt = keystrokeHandler._CancelIt = false ;
|
||||
|
||||
// Look for its definition availability.
|
||||
var keystrokeValue = keystrokeHandler.Keystrokes[ keyCombination ] ;
|
||||
|
||||
// FCKDebug.Output( 'KeyDown: ' + keyCombination + ' - Value: ' + keystrokeValue ) ;
|
||||
|
||||
// If the keystroke is defined
|
||||
if ( keystrokeValue )
|
||||
{
|
||||
// If the keystroke has been explicitly set to "true" OR calling the
|
||||
// "OnKeystroke" event, it doesn't return "true", the default behavior
|
||||
// must be preserved.
|
||||
if ( keystrokeValue === true || !( keystrokeHandler.OnKeystroke && keystrokeHandler.OnKeystroke.apply( keystrokeHandler, keystrokeValue ) ) )
|
||||
return true ;
|
||||
|
||||
cancelIt = true ;
|
||||
}
|
||||
|
||||
// By default, it will cancel all combinations with the CTRL key only (except positioning keys).
|
||||
if ( cancelIt || ( keystrokeHandler.CancelCtrlDefaults && keyModifiers == CTRL && ( keystroke < 33 || keystroke > 40 ) ) )
|
||||
{
|
||||
keystrokeHandler._CancelIt = true ;
|
||||
|
||||
if ( ev.preventDefault )
|
||||
return ev.preventDefault() ;
|
||||
|
||||
ev.returnValue = false ;
|
||||
ev.cancelBubble = true ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
function _FCKKeystrokeHandler_OnKeyPress( ev, keystrokeHandler )
|
||||
{
|
||||
if ( keystrokeHandler._CancelIt )
|
||||
{
|
||||
// FCKDebug.Output( 'KeyPress Cancel', 'Red') ;
|
||||
|
||||
if ( ev.preventDefault )
|
||||
return ev.preventDefault() ;
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Renders a list of menu items.
|
||||
*/
|
||||
|
||||
var FCKMenuBlock = function()
|
||||
{
|
||||
this._Items = new Array() ;
|
||||
}
|
||||
|
||||
|
||||
FCKMenuBlock.prototype.Count = function()
|
||||
{
|
||||
return this._Items.length ;
|
||||
}
|
||||
|
||||
FCKMenuBlock.prototype.AddItem = function( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled, customData )
|
||||
{
|
||||
var oItem = new FCKMenuItem( this, name, label, iconPathOrStripInfoArrayOrIndex, isDisabled, customData ) ;
|
||||
|
||||
oItem.OnClick = FCKTools.CreateEventListener( FCKMenuBlock_Item_OnClick, this ) ;
|
||||
oItem.OnActivate = FCKTools.CreateEventListener( FCKMenuBlock_Item_OnActivate, this ) ;
|
||||
|
||||
this._Items.push( oItem ) ;
|
||||
|
||||
return oItem ;
|
||||
}
|
||||
|
||||
FCKMenuBlock.prototype.AddSeparator = function()
|
||||
{
|
||||
this._Items.push( new FCKMenuSeparator() ) ;
|
||||
}
|
||||
|
||||
FCKMenuBlock.prototype.RemoveAllItems = function()
|
||||
{
|
||||
this._Items = new Array() ;
|
||||
|
||||
var eItemsTable = this._ItemsTable ;
|
||||
if ( eItemsTable )
|
||||
{
|
||||
while ( eItemsTable.rows.length > 0 )
|
||||
eItemsTable.deleteRow( 0 ) ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKMenuBlock.prototype.Create = function( parentElement )
|
||||
{
|
||||
if ( !this._ItemsTable )
|
||||
{
|
||||
if ( FCK.IECleanup )
|
||||
FCK.IECleanup.AddItem( this, FCKMenuBlock_Cleanup ) ;
|
||||
|
||||
this._Window = FCKTools.GetElementWindow( parentElement ) ;
|
||||
|
||||
var oDoc = FCKTools.GetElementDocument( parentElement ) ;
|
||||
|
||||
var eTable = parentElement.appendChild( oDoc.createElement( 'table' ) ) ;
|
||||
eTable.cellPadding = 0 ;
|
||||
eTable.cellSpacing = 0 ;
|
||||
|
||||
FCKTools.DisableSelection( eTable ) ;
|
||||
|
||||
var oMainElement = eTable.insertRow(-1).insertCell(-1) ;
|
||||
oMainElement.className = 'MN_Menu' ;
|
||||
|
||||
var eItemsTable = this._ItemsTable = oMainElement.appendChild( oDoc.createElement( 'table' ) ) ;
|
||||
eItemsTable.cellPadding = 0 ;
|
||||
eItemsTable.cellSpacing = 0 ;
|
||||
}
|
||||
|
||||
for ( var i = 0 ; i < this._Items.length ; i++ )
|
||||
this._Items[i].Create( this._ItemsTable ) ;
|
||||
}
|
||||
|
||||
/* Events */
|
||||
|
||||
function FCKMenuBlock_Item_OnClick( clickedItem, menuBlock )
|
||||
{
|
||||
if ( menuBlock.Hide )
|
||||
menuBlock.Hide() ;
|
||||
|
||||
FCKTools.RunFunction( menuBlock.OnClick, menuBlock, [ clickedItem ] ) ;
|
||||
}
|
||||
|
||||
function FCKMenuBlock_Item_OnActivate( menuBlock )
|
||||
{
|
||||
var oActiveItem = menuBlock._ActiveItem ;
|
||||
|
||||
if ( oActiveItem && oActiveItem != this )
|
||||
{
|
||||
// Set the focus to this menu block window (to fire OnBlur on opened panels).
|
||||
if ( !FCKBrowserInfo.IsIE && oActiveItem.HasSubMenu && !this.HasSubMenu )
|
||||
{
|
||||
menuBlock._Window.focus() ;
|
||||
|
||||
// Due to the event model provided by Opera, we need to set
|
||||
// HasFocus here as the above focus() call will not fire the focus
|
||||
// event in the panel immediately (#1200).
|
||||
menuBlock.Panel.HasFocus = true ;
|
||||
}
|
||||
|
||||
oActiveItem.Deactivate() ;
|
||||
}
|
||||
|
||||
menuBlock._ActiveItem = this ;
|
||||
}
|
||||
|
||||
function FCKMenuBlock_Cleanup()
|
||||
{
|
||||
this._Window = null ;
|
||||
this._ItemsTable = null ;
|
||||
}
|
||||
|
||||
// ################# //
|
||||
|
||||
var FCKMenuSeparator = function()
|
||||
{}
|
||||
|
||||
FCKMenuSeparator.prototype.Create = function( parentTable )
|
||||
{
|
||||
var oDoc = FCKTools.GetElementDocument( parentTable ) ;
|
||||
|
||||
var r = parentTable.insertRow(-1) ;
|
||||
|
||||
var eCell = r.insertCell(-1) ;
|
||||
eCell.className = 'MN_Separator MN_Icon' ;
|
||||
|
||||
eCell = r.insertCell(-1) ;
|
||||
eCell.className = 'MN_Separator' ;
|
||||
eCell.appendChild( oDoc.createElement( 'DIV' ) ).className = 'MN_Separator_Line' ;
|
||||
|
||||
eCell = r.insertCell(-1) ;
|
||||
eCell.className = 'MN_Separator' ;
|
||||
eCell.appendChild( oDoc.createElement( 'DIV' ) ).className = 'MN_Separator_Line' ;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* This class is a menu block that behaves like a panel. It's a mix of the
|
||||
* FCKMenuBlock and FCKPanel classes.
|
||||
*/
|
||||
|
||||
var FCKMenuBlockPanel = function()
|
||||
{
|
||||
// Call the "base" constructor.
|
||||
FCKMenuBlock.call( this ) ;
|
||||
}
|
||||
|
||||
FCKMenuBlockPanel.prototype = new FCKMenuBlock() ;
|
||||
|
||||
|
||||
// Override the create method.
|
||||
FCKMenuBlockPanel.prototype.Create = function()
|
||||
{
|
||||
var oPanel = this.Panel = ( this.Parent && this.Parent.Panel ? this.Parent.Panel.CreateChildPanel() : new FCKPanel() ) ;
|
||||
oPanel.AppendStyleSheet( FCKConfig.SkinEditorCSS ) ;
|
||||
|
||||
// Call the "base" implementation.
|
||||
FCKMenuBlock.prototype.Create.call( this, oPanel.MainNode ) ;
|
||||
}
|
||||
|
||||
FCKMenuBlockPanel.prototype.Show = function( x, y, relElement )
|
||||
{
|
||||
if ( !this.Panel.CheckIsOpened() )
|
||||
this.Panel.Show( x, y, relElement ) ;
|
||||
}
|
||||
|
||||
FCKMenuBlockPanel.prototype.Hide = function()
|
||||
{
|
||||
if ( this.Panel.CheckIsOpened() )
|
||||
this.Panel.Hide() ;
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Defines and renders a menu items in a menu block.
|
||||
*/
|
||||
|
||||
var FCKMenuItem = function( parentMenuBlock, name, label, iconPathOrStripInfoArray, isDisabled, customData )
|
||||
{
|
||||
this.Name = name ;
|
||||
this.Label = label || name ;
|
||||
this.IsDisabled = isDisabled ;
|
||||
|
||||
this.Icon = new FCKIcon( iconPathOrStripInfoArray ) ;
|
||||
|
||||
this.SubMenu = new FCKMenuBlockPanel() ;
|
||||
this.SubMenu.Parent = parentMenuBlock ;
|
||||
this.SubMenu.OnClick = FCKTools.CreateEventListener( FCKMenuItem_SubMenu_OnClick, this ) ;
|
||||
this.CustomData = customData ;
|
||||
|
||||
if ( FCK.IECleanup )
|
||||
FCK.IECleanup.AddItem( this, FCKMenuItem_Cleanup ) ;
|
||||
}
|
||||
|
||||
|
||||
FCKMenuItem.prototype.AddItem = function( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled, customData )
|
||||
{
|
||||
this.HasSubMenu = true ;
|
||||
return this.SubMenu.AddItem( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled, customData ) ;
|
||||
}
|
||||
|
||||
FCKMenuItem.prototype.AddSeparator = function()
|
||||
{
|
||||
this.SubMenu.AddSeparator() ;
|
||||
}
|
||||
|
||||
FCKMenuItem.prototype.Create = function( parentTable )
|
||||
{
|
||||
var bHasSubMenu = this.HasSubMenu ;
|
||||
|
||||
var oDoc = FCKTools.GetElementDocument( parentTable ) ;
|
||||
|
||||
// Add a row in the table to hold the menu item.
|
||||
var r = this.MainElement = parentTable.insertRow(-1) ;
|
||||
r.className = this.IsDisabled ? 'MN_Item_Disabled' : 'MN_Item' ;
|
||||
|
||||
// Set the row behavior.
|
||||
if ( !this.IsDisabled )
|
||||
{
|
||||
FCKTools.AddEventListenerEx( r, 'mouseover', FCKMenuItem_OnMouseOver, [ this ] ) ;
|
||||
FCKTools.AddEventListenerEx( r, 'click', FCKMenuItem_OnClick, [ this ] ) ;
|
||||
|
||||
if ( !bHasSubMenu )
|
||||
FCKTools.AddEventListenerEx( r, 'mouseout', FCKMenuItem_OnMouseOut, [ this ] ) ;
|
||||
}
|
||||
|
||||
// Create the icon cell.
|
||||
var eCell = r.insertCell(-1) ;
|
||||
eCell.className = 'MN_Icon' ;
|
||||
eCell.appendChild( this.Icon.CreateIconElement( oDoc ) ) ;
|
||||
|
||||
// Create the label cell.
|
||||
eCell = r.insertCell(-1) ;
|
||||
eCell.className = 'MN_Label' ;
|
||||
eCell.noWrap = true ;
|
||||
eCell.appendChild( oDoc.createTextNode( this.Label ) ) ;
|
||||
|
||||
// Create the arrow cell and setup the sub menu panel (if needed).
|
||||
eCell = r.insertCell(-1) ;
|
||||
if ( bHasSubMenu )
|
||||
{
|
||||
eCell.className = 'MN_Arrow' ;
|
||||
|
||||
// The arrow is a fixed size image.
|
||||
var eArrowImg = eCell.appendChild( oDoc.createElement( 'IMG' ) ) ;
|
||||
eArrowImg.src = FCK_IMAGES_PATH + 'arrow_' + FCKLang.Dir + '.gif' ;
|
||||
eArrowImg.width = 4 ;
|
||||
eArrowImg.height = 7 ;
|
||||
|
||||
this.SubMenu.Create() ;
|
||||
this.SubMenu.Panel.OnHide = FCKTools.CreateEventListener( FCKMenuItem_SubMenu_OnHide, this ) ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKMenuItem.prototype.Activate = function()
|
||||
{
|
||||
this.MainElement.className = 'MN_Item_Over' ;
|
||||
|
||||
if ( this.HasSubMenu )
|
||||
{
|
||||
// Show the child menu block. The ( +2, -2 ) correction is done because
|
||||
// of the padding in the skin. It is not a good solution because one
|
||||
// could change the skin and so the final result would not be accurate.
|
||||
// For now it is ok because we are controlling the skin.
|
||||
this.SubMenu.Show( this.MainElement.offsetWidth + 2, -2, this.MainElement ) ;
|
||||
}
|
||||
|
||||
FCKTools.RunFunction( this.OnActivate, this ) ;
|
||||
}
|
||||
|
||||
FCKMenuItem.prototype.Deactivate = function()
|
||||
{
|
||||
this.MainElement.className = 'MN_Item' ;
|
||||
|
||||
if ( this.HasSubMenu )
|
||||
this.SubMenu.Hide() ;
|
||||
}
|
||||
|
||||
/* Events */
|
||||
|
||||
function FCKMenuItem_SubMenu_OnClick( clickedItem, listeningItem )
|
||||
{
|
||||
FCKTools.RunFunction( listeningItem.OnClick, listeningItem, [ clickedItem ] ) ;
|
||||
}
|
||||
|
||||
function FCKMenuItem_SubMenu_OnHide( menuItem )
|
||||
{
|
||||
menuItem.Deactivate() ;
|
||||
}
|
||||
|
||||
function FCKMenuItem_OnClick( ev, menuItem )
|
||||
{
|
||||
if ( menuItem.HasSubMenu )
|
||||
menuItem.Activate() ;
|
||||
else
|
||||
{
|
||||
menuItem.Deactivate() ;
|
||||
FCKTools.RunFunction( menuItem.OnClick, menuItem, [ menuItem ] ) ;
|
||||
}
|
||||
}
|
||||
|
||||
function FCKMenuItem_OnMouseOver( ev, menuItem )
|
||||
{
|
||||
menuItem.Activate() ;
|
||||
}
|
||||
|
||||
function FCKMenuItem_OnMouseOut( ev, menuItem )
|
||||
{
|
||||
menuItem.Deactivate() ;
|
||||
}
|
||||
|
||||
function FCKMenuItem_Cleanup()
|
||||
{
|
||||
this.MainElement = null ;
|
||||
}
|
||||
386
_cubecart/CubeCart-4.3.0/admin/includes/rte/editor/_source/classes/fckpanel.js
Executable file
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Component that creates floating panels. It is used by many
|
||||
* other components, like the toolbar items, context menu, etc...
|
||||
*/
|
||||
|
||||
var FCKPanel = function( parentWindow )
|
||||
{
|
||||
this.IsRTL = ( FCKLang.Dir == 'rtl' ) ;
|
||||
this.IsContextMenu = false ;
|
||||
this._LockCounter = 0 ;
|
||||
|
||||
this._Window = parentWindow || window ;
|
||||
|
||||
var oDocument ;
|
||||
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
{
|
||||
// Create the Popup that will hold the panel.
|
||||
// The popup has to be created before playing with domain hacks, see #1666.
|
||||
this._Popup = this._Window.createPopup() ;
|
||||
|
||||
// this._Window cannot be accessed while playing with domain hacks, but local variable is ok.
|
||||
// See #1666.
|
||||
var pDoc = this._Window.document ;
|
||||
|
||||
// This is a trick to IE6 (not IE7). The original domain must be set
|
||||
// before creating the popup, so we are able to take a refence to the
|
||||
// document inside of it, and the set the proper domain for it. (#123)
|
||||
if ( FCK_IS_CUSTOM_DOMAIN && !FCKBrowserInfo.IsIE7 )
|
||||
{
|
||||
pDoc.domain = FCK_ORIGINAL_DOMAIN ;
|
||||
document.domain = FCK_ORIGINAL_DOMAIN ;
|
||||
}
|
||||
|
||||
oDocument = this.Document = this._Popup.document ;
|
||||
|
||||
// Set the proper domain inside the popup.
|
||||
if ( FCK_IS_CUSTOM_DOMAIN )
|
||||
{
|
||||
oDocument.domain = FCK_RUNTIME_DOMAIN ;
|
||||
pDoc.domain = FCK_RUNTIME_DOMAIN ;
|
||||
document.domain = FCK_RUNTIME_DOMAIN ;
|
||||
}
|
||||
|
||||
FCK.IECleanup.AddItem( this, FCKPanel_Cleanup ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
var oIFrame = this._IFrame = this._Window.document.createElement('iframe') ;
|
||||
FCKTools.ResetStyles( oIFrame );
|
||||
oIFrame.src = 'javascript:void(0)' ;
|
||||
oIFrame.allowTransparency = true ;
|
||||
oIFrame.frameBorder = '0' ;
|
||||
oIFrame.scrolling = 'no' ;
|
||||
oIFrame.style.width = oIFrame.style.height = '0px' ;
|
||||
FCKDomTools.SetElementStyles( oIFrame,
|
||||
{
|
||||
position : 'absolute',
|
||||
zIndex : FCKConfig.FloatingPanelsZIndex
|
||||
} ) ;
|
||||
|
||||
this._Window.document.body.appendChild( oIFrame ) ;
|
||||
|
||||
var oIFrameWindow = oIFrame.contentWindow ;
|
||||
|
||||
oDocument = this.Document = oIFrameWindow.document ;
|
||||
|
||||
// Workaround for Safari 12256. Ticket #63
|
||||
var sBase = '' ;
|
||||
if ( FCKBrowserInfo.IsSafari )
|
||||
sBase = '<base href="' + window.document.location + '">' ;
|
||||
|
||||
// Initialize the IFRAME document body.
|
||||
oDocument.open() ;
|
||||
oDocument.write( '<html><head>' + sBase + '<\/head><body style="margin:0px;padding:0px;"><\/body><\/html>' ) ;
|
||||
oDocument.close() ;
|
||||
|
||||
if( FCKBrowserInfo.IsAIR )
|
||||
FCKAdobeAIR.Panel_Contructor( oDocument, window.document.location ) ;
|
||||
|
||||
FCKTools.AddEventListenerEx( oIFrameWindow, 'focus', FCKPanel_Window_OnFocus, this ) ;
|
||||
FCKTools.AddEventListenerEx( oIFrameWindow, 'blur', FCKPanel_Window_OnBlur, this ) ;
|
||||
}
|
||||
|
||||
oDocument.dir = FCKLang.Dir ;
|
||||
|
||||
FCKTools.AddEventListener( oDocument, 'contextmenu', FCKTools.CancelEvent ) ;
|
||||
|
||||
|
||||
// Create the main DIV that is used as the panel base.
|
||||
this.MainNode = oDocument.body.appendChild( oDocument.createElement('DIV') ) ;
|
||||
|
||||
// The "float" property must be set so Firefox calculates the size correctly.
|
||||
this.MainNode.style.cssFloat = this.IsRTL ? 'right' : 'left' ;
|
||||
}
|
||||
|
||||
|
||||
FCKPanel.prototype.AppendStyleSheet = function( styleSheet )
|
||||
{
|
||||
FCKTools.AppendStyleSheet( this.Document, styleSheet ) ;
|
||||
}
|
||||
|
||||
FCKPanel.prototype.Preload = function( x, y, relElement )
|
||||
{
|
||||
// The offsetWidth and offsetHeight properties are not available if the
|
||||
// element is not visible. So we must "show" the popup with no size to
|
||||
// be able to use that values in the second call (IE only).
|
||||
if ( this._Popup )
|
||||
this._Popup.show( x, y, 0, 0, relElement ) ;
|
||||
}
|
||||
|
||||
FCKPanel.prototype.Show = function( x, y, relElement, width, height )
|
||||
{
|
||||
var iMainWidth ;
|
||||
var eMainNode = this.MainNode ;
|
||||
|
||||
if ( this._Popup )
|
||||
{
|
||||
// The offsetWidth and offsetHeight properties are not available if the
|
||||
// element is not visible. So we must "show" the popup with no size to
|
||||
// be able to use that values in the second call.
|
||||
this._Popup.show( x, y, 0, 0, relElement ) ;
|
||||
|
||||
// The following lines must be place after the above "show", otherwise it
|
||||
// doesn't has the desired effect.
|
||||
FCKDomTools.SetElementStyles( eMainNode,
|
||||
{
|
||||
width : width ? width + 'px' : '',
|
||||
height : height ? height + 'px' : ''
|
||||
} ) ;
|
||||
|
||||
iMainWidth = eMainNode.offsetWidth ;
|
||||
|
||||
if ( this.IsRTL )
|
||||
{
|
||||
if ( this.IsContextMenu )
|
||||
x = x - iMainWidth + 1 ;
|
||||
else if ( relElement )
|
||||
x = ( x * -1 ) + relElement.offsetWidth - iMainWidth ;
|
||||
}
|
||||
|
||||
// Second call: Show the Popup at the specified location, with the correct size.
|
||||
this._Popup.show( x, y, iMainWidth, eMainNode.offsetHeight, relElement ) ;
|
||||
|
||||
if ( this.OnHide )
|
||||
{
|
||||
if ( this._Timer )
|
||||
CheckPopupOnHide.call( this, true ) ;
|
||||
|
||||
this._Timer = FCKTools.SetInterval( CheckPopupOnHide, 100, this ) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do not fire OnBlur while the panel is opened.
|
||||
if ( typeof( FCK.ToolbarSet.CurrentInstance.FocusManager ) != 'undefined' )
|
||||
FCK.ToolbarSet.CurrentInstance.FocusManager.Lock() ;
|
||||
|
||||
if ( this.ParentPanel )
|
||||
{
|
||||
this.ParentPanel.Lock() ;
|
||||
|
||||
// Due to a bug on FF3, we must ensure that the parent panel will
|
||||
// blur (#1584).
|
||||
FCKPanel_Window_OnBlur( null, this.ParentPanel ) ;
|
||||
}
|
||||
|
||||
// Toggle the iframe scrolling attribute to prevent the panel
|
||||
// scrollbars from disappearing in FF Mac. (#191)
|
||||
if ( FCKBrowserInfo.IsGecko && FCKBrowserInfo.IsMac )
|
||||
{
|
||||
this._IFrame.scrolling = '' ;
|
||||
FCKTools.RunFunction( function(){ this._IFrame.scrolling = 'no'; }, this ) ;
|
||||
}
|
||||
|
||||
// Be sure we'll not have more than one Panel opened at the same time.
|
||||
// Do not unlock focus manager here because we're displaying another floating panel
|
||||
// instead of returning the editor to a "no panel" state (Bug #1514).
|
||||
if ( FCK.ToolbarSet.CurrentInstance.GetInstanceObject( 'FCKPanel' )._OpenedPanel &&
|
||||
FCK.ToolbarSet.CurrentInstance.GetInstanceObject( 'FCKPanel' )._OpenedPanel != this )
|
||||
FCK.ToolbarSet.CurrentInstance.GetInstanceObject( 'FCKPanel' )._OpenedPanel.Hide( false, true ) ;
|
||||
|
||||
FCKDomTools.SetElementStyles( eMainNode,
|
||||
{
|
||||
width : width ? width + 'px' : '',
|
||||
height : height ? height + 'px' : ''
|
||||
} ) ;
|
||||
|
||||
iMainWidth = eMainNode.offsetWidth ;
|
||||
|
||||
if ( !width ) this._IFrame.width = 1 ;
|
||||
if ( !height ) this._IFrame.height = 1 ;
|
||||
|
||||
// This is weird... but with Firefox, we must get the offsetWidth before
|
||||
// setting the _IFrame size (which returns "0"), and then after that,
|
||||
// to return the correct width. Remove the first step and it will not
|
||||
// work when the editor is in RTL.
|
||||
//
|
||||
// The "|| eMainNode.firstChild.offsetWidth" part has been added
|
||||
// for Opera compatibility (see #570).
|
||||
iMainWidth = eMainNode.offsetWidth || eMainNode.firstChild.offsetWidth ;
|
||||
|
||||
// Base the popup coordinates upon the coordinates of relElement.
|
||||
var oPos = FCKTools.GetDocumentPosition( this._Window,
|
||||
relElement.nodeType == 9 ?
|
||||
( FCKTools.IsStrictMode( relElement ) ? relElement.documentElement : relElement.body ) :
|
||||
relElement ) ;
|
||||
|
||||
// Minus the offsets provided by any positioned parent element of the panel iframe.
|
||||
var positionedAncestor = FCKDomTools.GetPositionedAncestor( this._IFrame.parentNode ) ;
|
||||
if ( positionedAncestor )
|
||||
{
|
||||
var nPos = FCKTools.GetDocumentPosition( FCKTools.GetElementWindow( positionedAncestor ), positionedAncestor ) ;
|
||||
oPos.x -= nPos.x ;
|
||||
oPos.y -= nPos.y ;
|
||||
}
|
||||
|
||||
if ( this.IsRTL && !this.IsContextMenu )
|
||||
x = ( x * -1 ) ;
|
||||
|
||||
x += oPos.x ;
|
||||
y += oPos.y ;
|
||||
|
||||
if ( this.IsRTL )
|
||||
{
|
||||
if ( this.IsContextMenu )
|
||||
x = x - iMainWidth + 1 ;
|
||||
else if ( relElement )
|
||||
x = x + relElement.offsetWidth - iMainWidth ;
|
||||
}
|
||||
else
|
||||
{
|
||||
var oViewPaneSize = FCKTools.GetViewPaneSize( this._Window ) ;
|
||||
var oScrollPosition = FCKTools.GetScrollPosition( this._Window ) ;
|
||||
|
||||
var iViewPaneHeight = oViewPaneSize.Height + oScrollPosition.Y ;
|
||||
var iViewPaneWidth = oViewPaneSize.Width + oScrollPosition.X ;
|
||||
|
||||
if ( ( x + iMainWidth ) > iViewPaneWidth )
|
||||
x -= x + iMainWidth - iViewPaneWidth ;
|
||||
|
||||
if ( ( y + eMainNode.offsetHeight ) > iViewPaneHeight )
|
||||
y -= y + eMainNode.offsetHeight - iViewPaneHeight ;
|
||||
}
|
||||
|
||||
// Set the context menu DIV in the specified location.
|
||||
FCKDomTools.SetElementStyles( this._IFrame,
|
||||
{
|
||||
left : x + 'px',
|
||||
top : y + 'px'
|
||||
} ) ;
|
||||
|
||||
// Move the focus to the IFRAME so we catch the "onblur".
|
||||
this._IFrame.contentWindow.focus() ;
|
||||
this._IsOpened = true ;
|
||||
|
||||
var me = this ;
|
||||
this._resizeTimer = setTimeout( function()
|
||||
{
|
||||
var iWidth = eMainNode.offsetWidth || eMainNode.firstChild.offsetWidth ;
|
||||
var iHeight = eMainNode.offsetHeight ;
|
||||
me._IFrame.style.width = iWidth + 'px' ;
|
||||
me._IFrame.style.height = iHeight + 'px' ;
|
||||
|
||||
}, 0 ) ;
|
||||
|
||||
FCK.ToolbarSet.CurrentInstance.GetInstanceObject( 'FCKPanel' )._OpenedPanel = this ;
|
||||
}
|
||||
|
||||
FCKTools.RunFunction( this.OnShow, this ) ;
|
||||
}
|
||||
|
||||
FCKPanel.prototype.Hide = function( ignoreOnHide, ignoreFocusManagerUnlock )
|
||||
{
|
||||
if ( this._Popup )
|
||||
this._Popup.hide() ;
|
||||
else
|
||||
{
|
||||
if ( !this._IsOpened || this._LockCounter > 0 )
|
||||
return ;
|
||||
|
||||
// Enable the editor to fire the "OnBlur".
|
||||
if ( typeof( FCKFocusManager ) != 'undefined' && !ignoreFocusManagerUnlock )
|
||||
FCKFocusManager.Unlock() ;
|
||||
|
||||
// It is better to set the sizes to 0, otherwise Firefox would have
|
||||
// rendering problems.
|
||||
this._IFrame.style.width = this._IFrame.style.height = '0px' ;
|
||||
|
||||
this._IsOpened = false ;
|
||||
|
||||
if ( this._resizeTimer )
|
||||
{
|
||||
clearTimeout( this._resizeTimer ) ;
|
||||
this._resizeTimer = null ;
|
||||
}
|
||||
|
||||
if ( this.ParentPanel )
|
||||
this.ParentPanel.Unlock() ;
|
||||
|
||||
if ( !ignoreOnHide )
|
||||
FCKTools.RunFunction( this.OnHide, this ) ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKPanel.prototype.CheckIsOpened = function()
|
||||
{
|
||||
if ( this._Popup )
|
||||
return this._Popup.isOpen ;
|
||||
else
|
||||
return this._IsOpened ;
|
||||
}
|
||||
|
||||
FCKPanel.prototype.CreateChildPanel = function()
|
||||
{
|
||||
var oWindow = this._Popup ? FCKTools.GetDocumentWindow( this.Document ) : this._Window ;
|
||||
|
||||
var oChildPanel = new FCKPanel( oWindow ) ;
|
||||
oChildPanel.ParentPanel = this ;
|
||||
|
||||
return oChildPanel ;
|
||||
}
|
||||
|
||||
FCKPanel.prototype.Lock = function()
|
||||
{
|
||||
this._LockCounter++ ;
|
||||
}
|
||||
|
||||
FCKPanel.prototype.Unlock = function()
|
||||
{
|
||||
if ( --this._LockCounter == 0 && !this.HasFocus )
|
||||
this.Hide() ;
|
||||
}
|
||||
|
||||
/* Events */
|
||||
|
||||
function FCKPanel_Window_OnFocus( e, panel )
|
||||
{
|
||||
panel.HasFocus = true ;
|
||||
}
|
||||
|
||||
function FCKPanel_Window_OnBlur( e, panel )
|
||||
{
|
||||
panel.HasFocus = false ;
|
||||
|
||||
if ( panel._LockCounter == 0 )
|
||||
FCKTools.RunFunction( panel.Hide, panel ) ;
|
||||
}
|
||||
|
||||
function CheckPopupOnHide( forceHide )
|
||||
{
|
||||
if ( forceHide || !this._Popup.isOpen )
|
||||
{
|
||||
window.clearInterval( this._Timer ) ;
|
||||
this._Timer = null ;
|
||||
|
||||
FCKTools.RunFunction( this.OnHide, this ) ;
|
||||
}
|
||||
}
|
||||
|
||||
function FCKPanel_Cleanup()
|
||||
{
|
||||
this._Popup = null ;
|
||||
this._Window = null ;
|
||||
this.Document = null ;
|
||||
this.MainNode = null ;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKPlugin Class: Represents a single plugin.
|
||||
*/
|
||||
|
||||
var FCKPlugin = function( name, availableLangs, basePath )
|
||||
{
|
||||
this.Name = name ;
|
||||
this.BasePath = basePath ? basePath : FCKConfig.PluginsPath ;
|
||||
this.Path = this.BasePath + name + '/' ;
|
||||
|
||||
if ( !availableLangs || availableLangs.length == 0 )
|
||||
this.AvailableLangs = new Array() ;
|
||||
else
|
||||
this.AvailableLangs = availableLangs.split(',') ;
|
||||
}
|
||||
|
||||
FCKPlugin.prototype.Load = function()
|
||||
{
|
||||
// Load the language file, if defined.
|
||||
if ( this.AvailableLangs.length > 0 )
|
||||
{
|
||||
var sLang ;
|
||||
|
||||
// Check if the plugin has the language file for the active language.
|
||||
if ( this.AvailableLangs.IndexOf( FCKLanguageManager.ActiveLanguage.Code ) >= 0 )
|
||||
sLang = FCKLanguageManager.ActiveLanguage.Code ;
|
||||
else
|
||||
// Load the default language file (first one) if the current one is not available.
|
||||
sLang = this.AvailableLangs[0] ;
|
||||
|
||||
// Add the main plugin script.
|
||||
LoadScript( this.Path + 'lang/' + sLang + '.js' ) ;
|
||||
}
|
||||
|
||||
// Add the main plugin script.
|
||||
LoadScript( this.Path + 'fckplugin.js' ) ;
|
||||
}
|
||||
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKSpecialCombo Class: represents a special combo.
|
||||
*/
|
||||
|
||||
var FCKSpecialCombo = function( caption, fieldWidth, panelWidth, panelMaxHeight, parentWindow )
|
||||
{
|
||||
// Default properties values.
|
||||
this.FieldWidth = fieldWidth || 100 ;
|
||||
this.PanelWidth = panelWidth || 150 ;
|
||||
this.PanelMaxHeight = panelMaxHeight || 150 ;
|
||||
this.Label = ' ' ;
|
||||
this.Caption = caption ;
|
||||
this.Tooltip = caption ;
|
||||
this.Style = FCK_TOOLBARITEM_ICONTEXT ;
|
||||
|
||||
this.Enabled = true ;
|
||||
|
||||
this.Items = new Object() ;
|
||||
|
||||
this._Panel = new FCKPanel( parentWindow || window ) ;
|
||||
this._Panel.AppendStyleSheet( FCKConfig.SkinEditorCSS ) ;
|
||||
this._PanelBox = this._Panel.MainNode.appendChild( this._Panel.Document.createElement( 'DIV' ) ) ;
|
||||
this._PanelBox.className = 'SC_Panel' ;
|
||||
this._PanelBox.style.width = this.PanelWidth + 'px' ;
|
||||
|
||||
this._PanelBox.innerHTML = '<table cellpadding="0" cellspacing="0" width="100%" style="TABLE-LAYOUT: fixed"><tr><td nowrap></td></tr></table>' ;
|
||||
|
||||
this._ItemsHolderEl = this._PanelBox.getElementsByTagName('TD')[0] ;
|
||||
|
||||
if ( FCK.IECleanup )
|
||||
FCK.IECleanup.AddItem( this, FCKSpecialCombo_Cleanup ) ;
|
||||
|
||||
// this._Panel.StyleSheet = FCKConfig.SkinPath + 'fck_contextmenu.css' ;
|
||||
// this._Panel.Create() ;
|
||||
// this._Panel.PanelDiv.className += ' SC_Panel' ;
|
||||
// this._Panel.PanelDiv.innerHTML = '<table cellpadding="0" cellspacing="0" width="100%" style="TABLE-LAYOUT: fixed"><tr><td nowrap></td></tr></table>' ;
|
||||
// this._ItemsHolderEl = this._Panel.PanelDiv.getElementsByTagName('TD')[0] ;
|
||||
}
|
||||
|
||||
function FCKSpecialCombo_ItemOnMouseOver()
|
||||
{
|
||||
this.className += ' SC_ItemOver' ;
|
||||
}
|
||||
|
||||
function FCKSpecialCombo_ItemOnMouseOut()
|
||||
{
|
||||
this.className = this.originalClass ;
|
||||
}
|
||||
|
||||
function FCKSpecialCombo_ItemOnClick( ev, specialCombo, itemId )
|
||||
{
|
||||
this.className = this.originalClass ;
|
||||
|
||||
specialCombo._Panel.Hide() ;
|
||||
|
||||
specialCombo.SetLabel( this.FCKItemLabel ) ;
|
||||
|
||||
if ( typeof( specialCombo.OnSelect ) == 'function' )
|
||||
specialCombo.OnSelect( itemId, this ) ;
|
||||
}
|
||||
|
||||
FCKSpecialCombo.prototype.ClearItems = function ()
|
||||
{
|
||||
if ( this.Items )
|
||||
this.Items = {} ;
|
||||
|
||||
var itemsholder = this._ItemsHolderEl ;
|
||||
while ( itemsholder.firstChild )
|
||||
itemsholder.removeChild( itemsholder.firstChild ) ;
|
||||
}
|
||||
|
||||
FCKSpecialCombo.prototype.AddItem = function( id, html, label, bgColor )
|
||||
{
|
||||
// <div class="SC_Item" onmouseover="this.className='SC_Item SC_ItemOver';" onmouseout="this.className='SC_Item';"><b>Bold 1</b></div>
|
||||
var oDiv = this._ItemsHolderEl.appendChild( this._Panel.Document.createElement( 'DIV' ) ) ;
|
||||
oDiv.className = oDiv.originalClass = 'SC_Item' ;
|
||||
oDiv.innerHTML = html ;
|
||||
oDiv.FCKItemLabel = label || id ;
|
||||
oDiv.Selected = false ;
|
||||
|
||||
// In IE, the width must be set so the borders are shown correctly when the content overflows.
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
oDiv.style.width = '100%' ;
|
||||
|
||||
if ( bgColor )
|
||||
oDiv.style.backgroundColor = bgColor ;
|
||||
|
||||
FCKTools.AddEventListenerEx( oDiv, 'mouseover', FCKSpecialCombo_ItemOnMouseOver ) ;
|
||||
FCKTools.AddEventListenerEx( oDiv, 'mouseout', FCKSpecialCombo_ItemOnMouseOut ) ;
|
||||
FCKTools.AddEventListenerEx( oDiv, 'click', FCKSpecialCombo_ItemOnClick, [ this, id ] ) ;
|
||||
|
||||
this.Items[ id.toString().toLowerCase() ] = oDiv ;
|
||||
|
||||
return oDiv ;
|
||||
}
|
||||
|
||||
FCKSpecialCombo.prototype.SelectItem = function( item )
|
||||
{
|
||||
if ( typeof item == 'string' )
|
||||
item = this.Items[ item.toString().toLowerCase() ] ;
|
||||
|
||||
if ( item )
|
||||
{
|
||||
item.className = item.originalClass = 'SC_ItemSelected' ;
|
||||
item.Selected = true ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKSpecialCombo.prototype.SelectItemByLabel = function( itemLabel, setLabel )
|
||||
{
|
||||
for ( var id in this.Items )
|
||||
{
|
||||
var oDiv = this.Items[id] ;
|
||||
|
||||
if ( oDiv.FCKItemLabel == itemLabel )
|
||||
{
|
||||
oDiv.className = oDiv.originalClass = 'SC_ItemSelected' ;
|
||||
oDiv.Selected = true ;
|
||||
|
||||
if ( setLabel )
|
||||
this.SetLabel( itemLabel ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FCKSpecialCombo.prototype.DeselectAll = function( clearLabel )
|
||||
{
|
||||
for ( var i in this.Items )
|
||||
{
|
||||
if ( !this.Items[i] ) continue;
|
||||
this.Items[i].className = this.Items[i].originalClass = 'SC_Item' ;
|
||||
this.Items[i].Selected = false ;
|
||||
}
|
||||
|
||||
if ( clearLabel )
|
||||
this.SetLabel( '' ) ;
|
||||
}
|
||||
|
||||
FCKSpecialCombo.prototype.SetLabelById = function( id )
|
||||
{
|
||||
id = id ? id.toString().toLowerCase() : '' ;
|
||||
|
||||
var oDiv = this.Items[ id ] ;
|
||||
this.SetLabel( oDiv ? oDiv.FCKItemLabel : '' ) ;
|
||||
}
|
||||
|
||||
FCKSpecialCombo.prototype.SetLabel = function( text )
|
||||
{
|
||||
text = ( !text || text.length == 0 ) ? ' ' : text ;
|
||||
|
||||
if ( text == this.Label )
|
||||
return ;
|
||||
|
||||
this.Label = text ;
|
||||
|
||||
var labelEl = this._LabelEl ;
|
||||
if ( labelEl )
|
||||
{
|
||||
labelEl.innerHTML = text ;
|
||||
|
||||
// It may happen that the label is some HTML, including tags. This
|
||||
// would be a problem because when the user click on those tags, the
|
||||
// combo will get the selection from the editing area. So we must
|
||||
// disable any kind of selection here.
|
||||
FCKTools.DisableSelection( labelEl ) ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKSpecialCombo.prototype.SetEnabled = function( isEnabled )
|
||||
{
|
||||
this.Enabled = isEnabled ;
|
||||
|
||||
// In IE it can happen when the page is reloaded that _OuterTable is null, so check its existence
|
||||
if ( this._OuterTable )
|
||||
this._OuterTable.className = isEnabled ? '' : 'SC_FieldDisabled' ;
|
||||
}
|
||||
|
||||
FCKSpecialCombo.prototype.Create = function( targetElement )
|
||||
{
|
||||
var oDoc = FCKTools.GetElementDocument( targetElement ) ;
|
||||
var eOuterTable = this._OuterTable = targetElement.appendChild( oDoc.createElement( 'TABLE' ) ) ;
|
||||
eOuterTable.cellPadding = 0 ;
|
||||
eOuterTable.cellSpacing = 0 ;
|
||||
|
||||
eOuterTable.insertRow(-1) ;
|
||||
|
||||
var sClass ;
|
||||
var bShowLabel ;
|
||||
|
||||
switch ( this.Style )
|
||||
{
|
||||
case FCK_TOOLBARITEM_ONLYICON :
|
||||
sClass = 'TB_ButtonType_Icon' ;
|
||||
bShowLabel = false;
|
||||
break ;
|
||||
case FCK_TOOLBARITEM_ONLYTEXT :
|
||||
sClass = 'TB_ButtonType_Text' ;
|
||||
bShowLabel = false;
|
||||
break ;
|
||||
case FCK_TOOLBARITEM_ICONTEXT :
|
||||
bShowLabel = true;
|
||||
break ;
|
||||
}
|
||||
|
||||
if ( this.Caption && this.Caption.length > 0 && bShowLabel )
|
||||
{
|
||||
var oCaptionCell = eOuterTable.rows[0].insertCell(-1) ;
|
||||
oCaptionCell.innerHTML = this.Caption ;
|
||||
oCaptionCell.className = 'SC_FieldCaption' ;
|
||||
}
|
||||
|
||||
// Create the main DIV element.
|
||||
var oField = FCKTools.AppendElement( eOuterTable.rows[0].insertCell(-1), 'div' ) ;
|
||||
if ( bShowLabel )
|
||||
{
|
||||
oField.className = 'SC_Field' ;
|
||||
oField.style.width = this.FieldWidth + 'px' ;
|
||||
oField.innerHTML = '<table width="100%" cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldLabel"><label> </label></td><td class="SC_FieldButton"> </td></tr></tbody></table>' ;
|
||||
|
||||
this._LabelEl = oField.getElementsByTagName('label')[0] ; // Memory Leak
|
||||
this._LabelEl.innerHTML = this.Label ;
|
||||
}
|
||||
else
|
||||
{
|
||||
oField.className = 'TB_Button_Off' ;
|
||||
//oField.innerHTML = '<span className="SC_FieldCaption">' + this.Caption + '<table cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldButton" style="border-left: none;"> </td></tr></tbody></table>' ;
|
||||
//oField.innerHTML = '<table cellpadding="0" cellspacing="0" style="TABLE-LAYOUT: fixed;"><tbody><tr><td class="SC_FieldButton" style="border-left: none;"> </td></tr></tbody></table>' ;
|
||||
|
||||
// Gets the correct CSS class to use for the specified style (param).
|
||||
oField.innerHTML = '<table title="' + this.Tooltip + '" class="' + sClass + '" cellspacing="0" cellpadding="0" border="0">' +
|
||||
'<tr>' +
|
||||
//'<td class="TB_Icon"><img src="' + FCKConfig.SkinPath + 'toolbar/' + this.Command.Name.toLowerCase() + '.gif" width="21" height="21"></td>' +
|
||||
'<td><img class="TB_Button_Padding" src="' + FCK_SPACER_PATH + '" /></td>' +
|
||||
'<td class="TB_Text">' + this.Caption + '</td>' +
|
||||
'<td><img class="TB_Button_Padding" src="' + FCK_SPACER_PATH + '" /></td>' +
|
||||
'<td class="TB_ButtonArrow"><img src="' + FCKConfig.SkinPath + 'images/toolbar.buttonarrow.gif" width="5" height="3"></td>' +
|
||||
'<td><img class="TB_Button_Padding" src="' + FCK_SPACER_PATH + '" /></td>' +
|
||||
'</tr>' +
|
||||
'</table>' ;
|
||||
}
|
||||
|
||||
|
||||
// Events Handlers
|
||||
|
||||
FCKTools.AddEventListenerEx( oField, 'mouseover', FCKSpecialCombo_OnMouseOver, this ) ;
|
||||
FCKTools.AddEventListenerEx( oField, 'mouseout', FCKSpecialCombo_OnMouseOut, this ) ;
|
||||
FCKTools.AddEventListenerEx( oField, 'click', FCKSpecialCombo_OnClick, this ) ;
|
||||
|
||||
FCKTools.DisableSelection( this._Panel.Document.body ) ;
|
||||
}
|
||||
|
||||
function FCKSpecialCombo_Cleanup()
|
||||
{
|
||||
this._LabelEl = null ;
|
||||
this._OuterTable = null ;
|
||||
this._ItemsHolderEl = null ;
|
||||
this._PanelBox = null ;
|
||||
|
||||
if ( this.Items )
|
||||
{
|
||||
for ( var key in this.Items )
|
||||
this.Items[key] = null ;
|
||||
}
|
||||
}
|
||||
|
||||
function FCKSpecialCombo_OnMouseOver( ev, specialCombo )
|
||||
{
|
||||
if ( specialCombo.Enabled )
|
||||
{
|
||||
switch ( specialCombo.Style )
|
||||
{
|
||||
case FCK_TOOLBARITEM_ONLYICON :
|
||||
this.className = 'TB_Button_On_Over';
|
||||
break ;
|
||||
case FCK_TOOLBARITEM_ONLYTEXT :
|
||||
this.className = 'TB_Button_On_Over';
|
||||
break ;
|
||||
case FCK_TOOLBARITEM_ICONTEXT :
|
||||
this.className = 'SC_Field SC_FieldOver' ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function FCKSpecialCombo_OnMouseOut( ev, specialCombo )
|
||||
{
|
||||
switch ( specialCombo.Style )
|
||||
{
|
||||
case FCK_TOOLBARITEM_ONLYICON :
|
||||
this.className = 'TB_Button_Off';
|
||||
break ;
|
||||
case FCK_TOOLBARITEM_ONLYTEXT :
|
||||
this.className = 'TB_Button_Off';
|
||||
break ;
|
||||
case FCK_TOOLBARITEM_ICONTEXT :
|
||||
this.className='SC_Field' ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
function FCKSpecialCombo_OnClick( e, specialCombo )
|
||||
{
|
||||
// For Mozilla we must stop the event propagation to avoid it hiding
|
||||
// the panel because of a click outside of it.
|
||||
// if ( e )
|
||||
// {
|
||||
// e.stopPropagation() ;
|
||||
// FCKPanelEventHandlers.OnDocumentClick( e ) ;
|
||||
// }
|
||||
|
||||
if ( specialCombo.Enabled )
|
||||
{
|
||||
var oPanel = specialCombo._Panel ;
|
||||
var oPanelBox = specialCombo._PanelBox ;
|
||||
var oItemsHolder = specialCombo._ItemsHolderEl ;
|
||||
var iMaxHeight = specialCombo.PanelMaxHeight ;
|
||||
|
||||
if ( specialCombo.OnBeforeClick )
|
||||
specialCombo.OnBeforeClick( specialCombo ) ;
|
||||
|
||||
// This is a tricky thing. We must call the "Load" function, otherwise
|
||||
// it will not be possible to retrieve "oItemsHolder.offsetHeight" (IE only).
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
oPanel.Preload( 0, this.offsetHeight, this ) ;
|
||||
|
||||
if ( oItemsHolder.offsetHeight > iMaxHeight )
|
||||
// {
|
||||
oPanelBox.style.height = iMaxHeight + 'px' ;
|
||||
|
||||
// if ( FCKBrowserInfo.IsGecko )
|
||||
// oPanelBox.style.overflow = '-moz-scrollbars-vertical' ;
|
||||
// }
|
||||
else
|
||||
oPanelBox.style.height = '' ;
|
||||
|
||||
// oPanel.PanelDiv.style.width = specialCombo.PanelWidth + 'px' ;
|
||||
|
||||
oPanel.Show( 0, this.offsetHeight, this ) ;
|
||||
}
|
||||
|
||||
// return false ;
|
||||
}
|
||||
|
||||
/*
|
||||
Sample Combo Field HTML output:
|
||||
|
||||
<div class="SC_Field" style="width: 80px;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" style="table-layout: fixed;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="SC_FieldLabel"><label> </label></td>
|
||||
<td class="SC_FieldButton"> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
*/
|
||||
1500
_cubecart/CubeCart-4.3.0/admin/includes/rte/editor/_source/classes/fckstyle.js
Executable file
103
_cubecart/CubeCart-4.3.0/admin/includes/rte/editor/_source/classes/fcktoolbar.js
Executable file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKToolbar Class: represents a toolbar in the toolbarset. It is a group of
|
||||
* toolbar items.
|
||||
*/
|
||||
|
||||
var FCKToolbar = function()
|
||||
{
|
||||
this.Items = new Array() ;
|
||||
}
|
||||
|
||||
FCKToolbar.prototype.AddItem = function( item )
|
||||
{
|
||||
return this.Items[ this.Items.length ] = item ;
|
||||
}
|
||||
|
||||
FCKToolbar.prototype.AddButton = function( name, label, tooltip, iconPathOrStripInfoArrayOrIndex, style, state )
|
||||
{
|
||||
if ( typeof( iconPathOrStripInfoArrayOrIndex ) == 'number' )
|
||||
iconPathOrStripInfoArrayOrIndex = [ this.DefaultIconsStrip, this.DefaultIconSize, iconPathOrStripInfoArrayOrIndex ] ;
|
||||
|
||||
var oButton = new FCKToolbarButtonUI( name, label, tooltip, iconPathOrStripInfoArrayOrIndex, style, state ) ;
|
||||
oButton._FCKToolbar = this ;
|
||||
oButton.OnClick = FCKToolbar_OnItemClick ;
|
||||
|
||||
return this.AddItem( oButton ) ;
|
||||
}
|
||||
|
||||
function FCKToolbar_OnItemClick( item )
|
||||
{
|
||||
var oToolbar = item._FCKToolbar ;
|
||||
|
||||
if ( oToolbar.OnItemClick )
|
||||
oToolbar.OnItemClick( oToolbar, item ) ;
|
||||
}
|
||||
|
||||
FCKToolbar.prototype.AddSeparator = function()
|
||||
{
|
||||
this.AddItem( new FCKToolbarSeparator() ) ;
|
||||
}
|
||||
|
||||
FCKToolbar.prototype.Create = function( parentElement )
|
||||
{
|
||||
var oDoc = FCKTools.GetElementDocument( parentElement ) ;
|
||||
|
||||
var e = oDoc.createElement( 'table' ) ;
|
||||
e.className = 'TB_Toolbar' ;
|
||||
e.style.styleFloat = e.style.cssFloat = ( FCKLang.Dir == 'ltr' ? 'left' : 'right' ) ;
|
||||
e.dir = FCKLang.Dir ;
|
||||
e.cellPadding = 0 ;
|
||||
e.cellSpacing = 0 ;
|
||||
|
||||
var targetRow = e.insertRow(-1) ;
|
||||
|
||||
// Insert the start cell.
|
||||
var eCell ;
|
||||
|
||||
if ( !this.HideStart )
|
||||
{
|
||||
eCell = targetRow.insertCell(-1) ;
|
||||
eCell.appendChild( oDoc.createElement( 'div' ) ).className = 'TB_Start' ;
|
||||
}
|
||||
|
||||
for ( var i = 0 ; i < this.Items.length ; i++ )
|
||||
{
|
||||
this.Items[i].Create( targetRow.insertCell(-1) ) ;
|
||||
}
|
||||
|
||||
// Insert the ending cell.
|
||||
if ( !this.HideEnd )
|
||||
{
|
||||
eCell = targetRow.insertCell(-1) ;
|
||||
eCell.appendChild( oDoc.createElement( 'div' ) ).className = 'TB_End' ;
|
||||
}
|
||||
|
||||
parentElement.appendChild( e ) ;
|
||||
}
|
||||
|
||||
var FCKToolbarSeparator = function()
|
||||
{}
|
||||
|
||||
FCKToolbarSeparator.prototype.Create = function( parentElement )
|
||||
{
|
||||
FCKTools.AppendElement( parentElement, 'div' ).className = 'TB_Separator' ;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKToolbarBreak Class: breaks the toolbars.
|
||||
* It makes it possible to force the toolbar to break to a new line.
|
||||
* This is the Gecko specific implementation.
|
||||
*/
|
||||
|
||||
var FCKToolbarBreak = function()
|
||||
{}
|
||||
|
||||
FCKToolbarBreak.prototype.Create = function( targetElement )
|
||||
{
|
||||
var oBreakDiv = targetElement.ownerDocument.createElement( 'div' ) ;
|
||||
|
||||
oBreakDiv.style.clear = oBreakDiv.style.cssFloat = FCKLang.Dir == 'rtl' ? 'right' : 'left' ;
|
||||
|
||||
targetElement.appendChild( oBreakDiv ) ;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKToolbarBreak Class: breaks the toolbars.
|
||||
* It makes it possible to force the toolbar to break to a new line.
|
||||
* This is the IE specific implementation.
|
||||
*/
|
||||
|
||||
var FCKToolbarBreak = function()
|
||||
{}
|
||||
|
||||
FCKToolbarBreak.prototype.Create = function( targetElement )
|
||||
{
|
||||
var oBreakDiv = FCKTools.GetElementDocument( targetElement ).createElement( 'div' ) ;
|
||||
|
||||
oBreakDiv.className = 'TB_Break' ;
|
||||
|
||||
oBreakDiv.style.clear = FCKLang.Dir == 'rtl' ? 'left' : 'right' ;
|
||||
|
||||
targetElement.appendChild( oBreakDiv ) ;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKToolbarButton Class: represents a button in the toolbar.
|
||||
*/
|
||||
|
||||
var FCKToolbarButton = function( commandName, label, tooltip, style, sourceView, contextSensitive, icon )
|
||||
{
|
||||
this.CommandName = commandName ;
|
||||
this.Label = label ;
|
||||
this.Tooltip = tooltip ;
|
||||
this.Style = style ;
|
||||
this.SourceView = sourceView ? true : false ;
|
||||
this.ContextSensitive = contextSensitive ? true : false ;
|
||||
|
||||
if ( icon == null )
|
||||
this.IconPath = FCKConfig.SkinPath + 'toolbar/' + commandName.toLowerCase() + '.gif' ;
|
||||
else if ( typeof( icon ) == 'number' )
|
||||
this.IconPath = [ FCKConfig.SkinPath + 'fck_strip.gif', 16, icon ] ;
|
||||
else
|
||||
this.IconPath = icon ;
|
||||
}
|
||||
|
||||
FCKToolbarButton.prototype.Create = function( targetElement )
|
||||
{
|
||||
this._UIButton = new FCKToolbarButtonUI( this.CommandName, this.Label, this.Tooltip, this.IconPath, this.Style ) ;
|
||||
this._UIButton.OnClick = this.Click ;
|
||||
this._UIButton._ToolbarButton = this ;
|
||||
this._UIButton.Create( targetElement ) ;
|
||||
}
|
||||
|
||||
FCKToolbarButton.prototype.RefreshState = function()
|
||||
{
|
||||
var uiButton = this._UIButton ;
|
||||
|
||||
if ( !uiButton )
|
||||
return ;
|
||||
|
||||
// Gets the actual state.
|
||||
var eState = FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( this.CommandName ).GetState() ;
|
||||
|
||||
// If there are no state changes than do nothing and return.
|
||||
if ( eState == uiButton.State ) return ;
|
||||
|
||||
// Sets the actual state.
|
||||
uiButton.ChangeState( eState ) ;
|
||||
}
|
||||
|
||||
FCKToolbarButton.prototype.Click = function()
|
||||
{
|
||||
var oToolbarButton = this._ToolbarButton || this ;
|
||||
FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( oToolbarButton.CommandName ).Execute() ;
|
||||
}
|
||||
|
||||
FCKToolbarButton.prototype.Enable = function()
|
||||
{
|
||||
this.RefreshState() ;
|
||||
}
|
||||
|
||||
FCKToolbarButton.prototype.Disable = function()
|
||||
{
|
||||
// Sets the actual state.
|
||||
this._UIButton.ChangeState( FCK_TRISTATE_DISABLED ) ;
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKToolbarButtonUI Class: interface representation of a toolbar button.
|
||||
*/
|
||||
|
||||
var FCKToolbarButtonUI = function( name, label, tooltip, iconPathOrStripInfoArray, style, state )
|
||||
{
|
||||
this.Name = name ;
|
||||
this.Label = label || name ;
|
||||
this.Tooltip = tooltip || this.Label ;
|
||||
this.Style = style || FCK_TOOLBARITEM_ONLYICON ;
|
||||
this.State = state || FCK_TRISTATE_OFF ;
|
||||
|
||||
this.Icon = new FCKIcon( iconPathOrStripInfoArray ) ;
|
||||
|
||||
if ( FCK.IECleanup )
|
||||
FCK.IECleanup.AddItem( this, FCKToolbarButtonUI_Cleanup ) ;
|
||||
}
|
||||
|
||||
|
||||
FCKToolbarButtonUI.prototype._CreatePaddingElement = function( document )
|
||||
{
|
||||
var oImg = document.createElement( 'IMG' ) ;
|
||||
oImg.className = 'TB_Button_Padding' ;
|
||||
oImg.src = FCK_SPACER_PATH ;
|
||||
return oImg ;
|
||||
}
|
||||
|
||||
FCKToolbarButtonUI.prototype.Create = function( parentElement )
|
||||
{
|
||||
var oDoc = FCKTools.GetElementDocument( parentElement ) ;
|
||||
|
||||
// Create the Main Element.
|
||||
var oMainElement = this.MainElement = oDoc.createElement( 'DIV' ) ;
|
||||
oMainElement.title = this.Tooltip ;
|
||||
|
||||
// The following will prevent the button from catching the focus.
|
||||
if ( FCKBrowserInfo.IsGecko )
|
||||
oMainElement.onmousedown = FCKTools.CancelEvent ;
|
||||
|
||||
FCKTools.AddEventListenerEx( oMainElement, 'mouseover', FCKToolbarButtonUI_OnMouseOver, this ) ;
|
||||
FCKTools.AddEventListenerEx( oMainElement, 'mouseout', FCKToolbarButtonUI_OnMouseOut, this ) ;
|
||||
FCKTools.AddEventListenerEx( oMainElement, 'click', FCKToolbarButtonUI_OnClick, this ) ;
|
||||
|
||||
this.ChangeState( this.State, true ) ;
|
||||
|
||||
if ( this.Style == FCK_TOOLBARITEM_ONLYICON && !this.ShowArrow )
|
||||
{
|
||||
// <td><div class="TB_Button_On" title="Smiley">{Image}</div></td>
|
||||
|
||||
oMainElement.appendChild( this.Icon.CreateIconElement( oDoc ) ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// <td><div class="TB_Button_On" title="Smiley"><table cellpadding="0" cellspacing="0"><tr><td>{Image}</td><td nowrap>Toolbar Button</td><td><img class="TB_Button_Padding"></td></tr></table></div></td>
|
||||
// <td><div class="TB_Button_On" title="Smiley"><table cellpadding="0" cellspacing="0"><tr><td><img class="TB_Button_Padding"></td><td nowrap>Toolbar Button</td><td><img class="TB_Button_Padding"></td></tr></table></div></td>
|
||||
|
||||
var oTable = oMainElement.appendChild( oDoc.createElement( 'TABLE' ) ) ;
|
||||
oTable.cellPadding = 0 ;
|
||||
oTable.cellSpacing = 0 ;
|
||||
|
||||
var oRow = oTable.insertRow(-1) ;
|
||||
|
||||
// The Image cell (icon or padding).
|
||||
var oCell = oRow.insertCell(-1) ;
|
||||
|
||||
if ( this.Style == FCK_TOOLBARITEM_ONLYICON || this.Style == FCK_TOOLBARITEM_ICONTEXT )
|
||||
oCell.appendChild( this.Icon.CreateIconElement( oDoc ) ) ;
|
||||
else
|
||||
oCell.appendChild( this._CreatePaddingElement( oDoc ) ) ;
|
||||
|
||||
if ( this.Style == FCK_TOOLBARITEM_ONLYTEXT || this.Style == FCK_TOOLBARITEM_ICONTEXT )
|
||||
{
|
||||
// The Text cell.
|
||||
oCell = oRow.insertCell(-1) ;
|
||||
oCell.className = 'TB_Button_Text' ;
|
||||
oCell.noWrap = true ;
|
||||
oCell.appendChild( oDoc.createTextNode( this.Label ) ) ;
|
||||
}
|
||||
|
||||
if ( this.ShowArrow )
|
||||
{
|
||||
if ( this.Style != FCK_TOOLBARITEM_ONLYICON )
|
||||
{
|
||||
// A padding cell.
|
||||
oRow.insertCell(-1).appendChild( this._CreatePaddingElement( oDoc ) ) ;
|
||||
}
|
||||
|
||||
oCell = oRow.insertCell(-1) ;
|
||||
var eImg = oCell.appendChild( oDoc.createElement( 'IMG' ) ) ;
|
||||
eImg.src = FCKConfig.SkinPath + 'images/toolbar.buttonarrow.gif' ;
|
||||
eImg.width = 5 ;
|
||||
eImg.height = 3 ;
|
||||
}
|
||||
|
||||
// The last padding cell.
|
||||
oCell = oRow.insertCell(-1) ;
|
||||
oCell.appendChild( this._CreatePaddingElement( oDoc ) ) ;
|
||||
}
|
||||
|
||||
parentElement.appendChild( oMainElement ) ;
|
||||
}
|
||||
|
||||
FCKToolbarButtonUI.prototype.ChangeState = function( newState, force )
|
||||
{
|
||||
if ( !force && this.State == newState )
|
||||
return ;
|
||||
|
||||
var e = this.MainElement ;
|
||||
|
||||
// In IE it can happen when the page is reloaded that MainElement is null, so exit here
|
||||
if ( !e )
|
||||
return ;
|
||||
|
||||
switch ( parseInt( newState, 10 ) )
|
||||
{
|
||||
case FCK_TRISTATE_OFF :
|
||||
e.className = 'TB_Button_Off' ;
|
||||
break ;
|
||||
|
||||
case FCK_TRISTATE_ON :
|
||||
e.className = 'TB_Button_On' ;
|
||||
break ;
|
||||
|
||||
case FCK_TRISTATE_DISABLED :
|
||||
e.className = 'TB_Button_Disabled' ;
|
||||
break ;
|
||||
}
|
||||
|
||||
this.State = newState ;
|
||||
}
|
||||
|
||||
function FCKToolbarButtonUI_OnMouseOver( ev, button )
|
||||
{
|
||||
if ( button.State == FCK_TRISTATE_OFF )
|
||||
this.className = 'TB_Button_Off_Over' ;
|
||||
else if ( button.State == FCK_TRISTATE_ON )
|
||||
this.className = 'TB_Button_On_Over' ;
|
||||
}
|
||||
|
||||
function FCKToolbarButtonUI_OnMouseOut( ev, button )
|
||||
{
|
||||
if ( button.State == FCK_TRISTATE_OFF )
|
||||
this.className = 'TB_Button_Off' ;
|
||||
else if ( button.State == FCK_TRISTATE_ON )
|
||||
this.className = 'TB_Button_On' ;
|
||||
}
|
||||
|
||||
function FCKToolbarButtonUI_OnClick( ev, button )
|
||||
{
|
||||
if ( button.OnClick && button.State != FCK_TRISTATE_DISABLED )
|
||||
button.OnClick( button ) ;
|
||||
}
|
||||
|
||||
function FCKToolbarButtonUI_Cleanup()
|
||||
{
|
||||
// This one should not cause memory leak, but just for safety, let's clean
|
||||
// it up.
|
||||
this.MainElement = null ;
|
||||
}
|
||||
|
||||
/*
|
||||
Sample outputs:
|
||||
|
||||
This is the base structure. The variation is the image that is marked as {Image}:
|
||||
<td><div class="TB_Button_On" title="Smiley">{Image}</div></td>
|
||||
<td><div class="TB_Button_On" title="Smiley"><table cellpadding="0" cellspacing="0"><tr><td>{Image}</td><td nowrap>Toolbar Button</td><td><img class="TB_Button_Padding"></td></tr></table></div></td>
|
||||
<td><div class="TB_Button_On" title="Smiley"><table cellpadding="0" cellspacing="0"><tr><td><img class="TB_Button_Padding"></td><td nowrap>Toolbar Button</td><td><img class="TB_Button_Padding"></td></tr></table></div></td>
|
||||
|
||||
These are samples of possible {Image} values:
|
||||
|
||||
Strip - IE version:
|
||||
<div class="TB_Button_Image"><img src="strip.gif" style="top:-16px"></div>
|
||||
|
||||
Strip : Firefox, Safari and Opera version
|
||||
<img class="TB_Button_Image" style="background-position: 0px -16px;background-image: url(strip.gif);">
|
||||
|
||||
No-Strip : Browser independent:
|
||||
<img class="TB_Button_Image" src="smiley.gif">
|
||||
*/
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKToolbarPanelButton Class: Handles the Fonts combo selector.
|
||||
*/
|
||||
|
||||
var FCKToolbarFontFormatCombo = function( tooltip, style )
|
||||
{
|
||||
if ( tooltip === false )
|
||||
return ;
|
||||
|
||||
this.CommandName = 'FontFormat' ;
|
||||
this.Label = this.GetLabel() ;
|
||||
this.Tooltip = tooltip ? tooltip : this.Label ;
|
||||
this.Style = style ? style : FCK_TOOLBARITEM_ICONTEXT ;
|
||||
|
||||
this.NormalLabel = 'Normal' ;
|
||||
|
||||
this.PanelWidth = 190 ;
|
||||
|
||||
this.DefaultLabel = FCKConfig.DefaultFontFormatLabel || '' ;
|
||||
}
|
||||
|
||||
// Inherit from FCKToolbarSpecialCombo.
|
||||
FCKToolbarFontFormatCombo.prototype = new FCKToolbarStyleCombo( false ) ;
|
||||
|
||||
FCKToolbarFontFormatCombo.prototype.GetLabel = function()
|
||||
{
|
||||
return FCKLang.FontFormat ;
|
||||
}
|
||||
|
||||
FCKToolbarFontFormatCombo.prototype.GetStyles = function()
|
||||
{
|
||||
var styles = {} ;
|
||||
|
||||
// Get the format names from the language file.
|
||||
var aNames = FCKLang['FontFormats'].split(';') ;
|
||||
var oNames = {
|
||||
p : aNames[0],
|
||||
pre : aNames[1],
|
||||
address : aNames[2],
|
||||
h1 : aNames[3],
|
||||
h2 : aNames[4],
|
||||
h3 : aNames[5],
|
||||
h4 : aNames[6],
|
||||
h5 : aNames[7],
|
||||
h6 : aNames[8],
|
||||
div : aNames[9] || ( aNames[0] + ' (DIV)')
|
||||
} ;
|
||||
|
||||
// Get the available formats from the configuration file.
|
||||
var elements = FCKConfig.FontFormats.split(';') ;
|
||||
|
||||
for ( var i = 0 ; i < elements.length ; i++ )
|
||||
{
|
||||
var elementName = elements[ i ] ;
|
||||
var style = FCKStyles.GetStyle( '_FCK_' + elementName ) ;
|
||||
if ( style )
|
||||
{
|
||||
style.Label = oNames[ elementName ] ;
|
||||
styles[ '_FCK_' + elementName ] = style ;
|
||||
}
|
||||
else
|
||||
alert( "The FCKConfig.CoreStyles['" + elementName + "'] setting was not found. Please check the fckconfig.js file" ) ;
|
||||
}
|
||||
|
||||
return styles ;
|
||||
}
|
||||
|
||||
FCKToolbarFontFormatCombo.prototype.RefreshActiveItems = function( targetSpecialCombo )
|
||||
{
|
||||
var startElement = FCK.ToolbarSet.CurrentInstance.Selection.GetBoundaryParentElement( true ) ;
|
||||
|
||||
if ( startElement )
|
||||
{
|
||||
var path = new FCKElementPath( startElement ) ;
|
||||
var blockElement = path.Block ;
|
||||
|
||||
if ( blockElement )
|
||||
{
|
||||
for ( var i in targetSpecialCombo.Items )
|
||||
{
|
||||
var item = targetSpecialCombo.Items[i] ;
|
||||
var style = item.Style ;
|
||||
|
||||
if ( style.CheckElementRemovable( blockElement ) )
|
||||
{
|
||||
targetSpecialCombo.SetLabel( style.Label ) ;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
targetSpecialCombo.SetLabel( this.DefaultLabel ) ;
|
||||
}
|
||||
|
||||
FCKToolbarFontFormatCombo.prototype.StyleCombo_OnBeforeClick = function( targetSpecialCombo )
|
||||
{
|
||||
// Clear the current selection.
|
||||
targetSpecialCombo.DeselectAll() ;
|
||||
|
||||
var startElement = FCK.ToolbarSet.CurrentInstance.Selection.GetBoundaryParentElement( true ) ;
|
||||
|
||||
if ( startElement )
|
||||
{
|
||||
var path = new FCKElementPath( startElement ) ;
|
||||
var blockElement = path.Block ;
|
||||
|
||||
for ( var i in targetSpecialCombo.Items )
|
||||
{
|
||||
var item = targetSpecialCombo.Items[i] ;
|
||||
var style = item.Style ;
|
||||
|
||||
if ( style.CheckElementRemovable( blockElement ) )
|
||||
{
|
||||
targetSpecialCombo.SelectItem( item ) ;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKToolbarPanelButton Class: Handles the Fonts combo selector.
|
||||
*/
|
||||
|
||||
var FCKToolbarFontsCombo = function( tooltip, style )
|
||||
{
|
||||
this.CommandName = 'FontName' ;
|
||||
this.Label = this.GetLabel() ;
|
||||
this.Tooltip = tooltip ? tooltip : this.Label ;
|
||||
this.Style = style ? style : FCK_TOOLBARITEM_ICONTEXT ;
|
||||
|
||||
this.DefaultLabel = FCKConfig.DefaultFontLabel || '' ;
|
||||
}
|
||||
|
||||
// Inherit from FCKToolbarSpecialCombo.
|
||||
FCKToolbarFontsCombo.prototype = new FCKToolbarFontFormatCombo( false ) ;
|
||||
|
||||
FCKToolbarFontsCombo.prototype.GetLabel = function()
|
||||
{
|
||||
return FCKLang.Font ;
|
||||
}
|
||||
|
||||
FCKToolbarFontsCombo.prototype.GetStyles = function()
|
||||
{
|
||||
var baseStyle = FCKStyles.GetStyle( '_FCK_FontFace' ) ;
|
||||
|
||||
if ( !baseStyle )
|
||||
{
|
||||
alert( "The FCKConfig.CoreStyles['Size'] setting was not found. Please check the fckconfig.js file" ) ;
|
||||
return {} ;
|
||||
}
|
||||
|
||||
var styles = {} ;
|
||||
|
||||
var fonts = FCKConfig.FontNames.split(';') ;
|
||||
|
||||
for ( var i = 0 ; i < fonts.length ; i++ )
|
||||
{
|
||||
var fontParts = fonts[i].split('/') ;
|
||||
var font = fontParts[0] ;
|
||||
var caption = fontParts[1] || font ;
|
||||
|
||||
var style = FCKTools.CloneObject( baseStyle ) ;
|
||||
|
||||
style.SetVariable( 'Font', font ) ;
|
||||
style.Label = caption ;
|
||||
|
||||
styles[ caption ] = style ;
|
||||
}
|
||||
|
||||
return styles ;
|
||||
}
|
||||
|
||||
FCKToolbarFontsCombo.prototype.RefreshActiveItems = FCKToolbarStyleCombo.prototype.RefreshActiveItems ;
|
||||
|
||||
FCKToolbarFontsCombo.prototype.StyleCombo_OnBeforeClick = function( targetSpecialCombo )
|
||||
{
|
||||
// Clear the current selection.
|
||||
targetSpecialCombo.DeselectAll() ;
|
||||
|
||||
var startElement = FCKSelection.GetBoundaryParentElement( true ) ;
|
||||
|
||||
if ( startElement )
|
||||
{
|
||||
var path = new FCKElementPath( startElement ) ;
|
||||
|
||||
for ( var i in targetSpecialCombo.Items )
|
||||
{
|
||||
var item = targetSpecialCombo.Items[i] ;
|
||||
var style = item.Style ;
|
||||
|
||||
if ( style.CheckActive( path ) )
|
||||
{
|
||||
targetSpecialCombo.SelectItem( item ) ;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKToolbarPanelButton Class: Handles the Fonts combo selector.
|
||||
*/
|
||||
|
||||
var FCKToolbarFontSizeCombo = function( tooltip, style )
|
||||
{
|
||||
this.CommandName = 'FontSize' ;
|
||||
this.Label = this.GetLabel() ;
|
||||
this.Tooltip = tooltip ? tooltip : this.Label ;
|
||||
this.Style = style ? style : FCK_TOOLBARITEM_ICONTEXT ;
|
||||
|
||||
this.DefaultLabel = FCKConfig.DefaultFontSizeLabel || '' ;
|
||||
|
||||
this.FieldWidth = 70 ;
|
||||
}
|
||||
|
||||
// Inherit from FCKToolbarSpecialCombo.
|
||||
FCKToolbarFontSizeCombo.prototype = new FCKToolbarFontFormatCombo( false ) ;
|
||||
|
||||
FCKToolbarFontSizeCombo.prototype.GetLabel = function()
|
||||
{
|
||||
return FCKLang.FontSize ;
|
||||
}
|
||||
|
||||
FCKToolbarFontSizeCombo.prototype.GetStyles = function()
|
||||
{
|
||||
var baseStyle = FCKStyles.GetStyle( '_FCK_Size' ) ;
|
||||
|
||||
if ( !baseStyle )
|
||||
{
|
||||
alert( "The FCKConfig.CoreStyles['FontFace'] setting was not found. Please check the fckconfig.js file" ) ;
|
||||
return {} ;
|
||||
}
|
||||
|
||||
var styles = {} ;
|
||||
|
||||
var fonts = FCKConfig.FontSizes.split(';') ;
|
||||
|
||||
for ( var i = 0 ; i < fonts.length ; i++ )
|
||||
{
|
||||
var fontParts = fonts[i].split('/') ;
|
||||
var font = fontParts[0] ;
|
||||
var caption = fontParts[1] || font ;
|
||||
|
||||
var style = FCKTools.CloneObject( baseStyle ) ;
|
||||
style.SetVariable( 'Size', font ) ;
|
||||
style.Label = caption ;
|
||||
|
||||
styles[ caption ] = style ;
|
||||
}
|
||||
|
||||
return styles ;
|
||||
}
|
||||
|
||||
FCKToolbarFontSizeCombo.prototype.RefreshActiveItems = FCKToolbarStyleCombo.prototype.RefreshActiveItems ;
|
||||
|
||||
FCKToolbarFontSizeCombo.prototype.StyleCombo_OnBeforeClick = FCKToolbarFontsCombo.prototype.StyleCombo_OnBeforeClick ;
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKToolbarPanelButton Class: represents a special button in the toolbar
|
||||
* that shows a panel when pressed.
|
||||
*/
|
||||
|
||||
var FCKToolbarPanelButton = function( commandName, label, tooltip, style, icon )
|
||||
{
|
||||
this.CommandName = commandName ;
|
||||
|
||||
var oIcon ;
|
||||
|
||||
if ( icon == null )
|
||||
oIcon = FCKConfig.SkinPath + 'toolbar/' + commandName.toLowerCase() + '.gif' ;
|
||||
else if ( typeof( icon ) == 'number' )
|
||||
oIcon = [ FCKConfig.SkinPath + 'fck_strip.gif', 16, icon ] ;
|
||||
|
||||
var oUIButton = this._UIButton = new FCKToolbarButtonUI( commandName, label, tooltip, oIcon, style ) ;
|
||||
oUIButton._FCKToolbarPanelButton = this ;
|
||||
oUIButton.ShowArrow = true ;
|
||||
oUIButton.OnClick = FCKToolbarPanelButton_OnButtonClick ;
|
||||
}
|
||||
|
||||
FCKToolbarPanelButton.prototype.TypeName = 'FCKToolbarPanelButton' ;
|
||||
|
||||
FCKToolbarPanelButton.prototype.Create = function( parentElement )
|
||||
{
|
||||
parentElement.className += 'Menu' ;
|
||||
|
||||
this._UIButton.Create( parentElement ) ;
|
||||
|
||||
var oPanel = FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( this.CommandName )._Panel ;
|
||||
this.RegisterPanel( oPanel ) ;
|
||||
}
|
||||
|
||||
FCKToolbarPanelButton.prototype.RegisterPanel = function( oPanel )
|
||||
{
|
||||
if ( oPanel._FCKToolbarPanelButton )
|
||||
return ;
|
||||
|
||||
oPanel._FCKToolbarPanelButton = this ;
|
||||
|
||||
var eLineDiv = oPanel.Document.body.appendChild( oPanel.Document.createElement( 'div' ) ) ;
|
||||
eLineDiv.style.position = 'absolute' ;
|
||||
eLineDiv.style.top = '0px' ;
|
||||
|
||||
var eLine = oPanel._FCKToolbarPanelButtonLineDiv = eLineDiv.appendChild( oPanel.Document.createElement( 'IMG' ) ) ;
|
||||
eLine.className = 'TB_ConnectionLine' ;
|
||||
eLine.style.position = 'absolute' ;
|
||||
// eLine.style.backgroundColor = 'Red' ;
|
||||
eLine.src = FCK_SPACER_PATH ;
|
||||
|
||||
oPanel.OnHide = FCKToolbarPanelButton_OnPanelHide ;
|
||||
}
|
||||
|
||||
/*
|
||||
Events
|
||||
*/
|
||||
|
||||
function FCKToolbarPanelButton_OnButtonClick( toolbarButton )
|
||||
{
|
||||
var oButton = this._FCKToolbarPanelButton ;
|
||||
var e = oButton._UIButton.MainElement ;
|
||||
|
||||
oButton._UIButton.ChangeState( FCK_TRISTATE_ON ) ;
|
||||
|
||||
// oButton.LineImg.style.width = ( e.offsetWidth - 2 ) + 'px' ;
|
||||
|
||||
var oCommand = FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( oButton.CommandName ) ;
|
||||
var oPanel = oCommand._Panel ;
|
||||
oPanel._FCKToolbarPanelButtonLineDiv.style.width = ( e.offsetWidth - 2 ) + 'px' ;
|
||||
oCommand.Execute( 0, e.offsetHeight - 1, e ) ; // -1 to be over the border
|
||||
}
|
||||
|
||||
function FCKToolbarPanelButton_OnPanelHide()
|
||||
{
|
||||
var oMenuButton = this._FCKToolbarPanelButton ;
|
||||
oMenuButton._UIButton.ChangeState( FCK_TRISTATE_OFF ) ;
|
||||
}
|
||||
|
||||
// The Panel Button works like a normal button so the refresh state functions
|
||||
// defined for the normal button can be reused here.
|
||||
FCKToolbarPanelButton.prototype.RefreshState = FCKToolbarButton.prototype.RefreshState ;
|
||||
FCKToolbarPanelButton.prototype.Enable = FCKToolbarButton.prototype.Enable ;
|
||||
FCKToolbarPanelButton.prototype.Disable = FCKToolbarButton.prototype.Disable ;
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKToolbarSpecialCombo Class: This is a "abstract" base class to be used
|
||||
* by the special combo toolbar elements like font name, font size, paragraph format, etc...
|
||||
*
|
||||
* The following properties and methods must be implemented when inheriting from
|
||||
* this class:
|
||||
* - Property: CommandName [ The command name to be executed ]
|
||||
* - Method: GetLabel() [ Returns the label ]
|
||||
* - CreateItems( targetSpecialCombo ) [ Add all items in the special combo ]
|
||||
*/
|
||||
|
||||
var FCKToolbarSpecialCombo = function()
|
||||
{
|
||||
this.SourceView = false ;
|
||||
this.ContextSensitive = true ;
|
||||
this.FieldWidth = null ;
|
||||
this.PanelWidth = null ;
|
||||
this.PanelMaxHeight = null ;
|
||||
//this._LastValue = null ;
|
||||
}
|
||||
|
||||
|
||||
FCKToolbarSpecialCombo.prototype.DefaultLabel = '' ;
|
||||
|
||||
function FCKToolbarSpecialCombo_OnSelect( itemId, item )
|
||||
{
|
||||
FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( this.CommandName ).Execute( itemId, item ) ;
|
||||
}
|
||||
|
||||
FCKToolbarSpecialCombo.prototype.Create = function( targetElement )
|
||||
{
|
||||
this._Combo = new FCKSpecialCombo( this.GetLabel(), this.FieldWidth, this.PanelWidth, this.PanelMaxHeight, FCKBrowserInfo.IsIE ? window : FCKTools.GetElementWindow( targetElement ).parent ) ;
|
||||
|
||||
/*
|
||||
this._Combo.FieldWidth = this.FieldWidth != null ? this.FieldWidth : 100 ;
|
||||
this._Combo.PanelWidth = this.PanelWidth != null ? this.PanelWidth : 150 ;
|
||||
this._Combo.PanelMaxHeight = this.PanelMaxHeight != null ? this.PanelMaxHeight : 150 ;
|
||||
*/
|
||||
|
||||
//this._Combo.Command.Name = this.Command.Name;
|
||||
// this._Combo.Label = this.Label ;
|
||||
this._Combo.Tooltip = this.Tooltip ;
|
||||
this._Combo.Style = this.Style ;
|
||||
|
||||
this.CreateItems( this._Combo ) ;
|
||||
|
||||
this._Combo.Create( targetElement ) ;
|
||||
|
||||
this._Combo.CommandName = this.CommandName ;
|
||||
|
||||
this._Combo.OnSelect = FCKToolbarSpecialCombo_OnSelect ;
|
||||
}
|
||||
|
||||
function FCKToolbarSpecialCombo_RefreshActiveItems( combo, value )
|
||||
{
|
||||
combo.DeselectAll() ;
|
||||
combo.SelectItem( value ) ;
|
||||
combo.SetLabelById( value ) ;
|
||||
}
|
||||
|
||||
FCKToolbarSpecialCombo.prototype.RefreshState = function()
|
||||
{
|
||||
// Gets the actual state.
|
||||
var eState ;
|
||||
|
||||
// if ( FCK.EditMode == FCK_EDITMODE_SOURCE && ! this.SourceView )
|
||||
// eState = FCK_TRISTATE_DISABLED ;
|
||||
// else
|
||||
// {
|
||||
var sValue = FCK.ToolbarSet.CurrentInstance.Commands.GetCommand( this.CommandName ).GetState() ;
|
||||
|
||||
// FCKDebug.Output( 'RefreshState of Special Combo "' + this.TypeOf + '" - State: ' + sValue ) ;
|
||||
|
||||
if ( sValue != FCK_TRISTATE_DISABLED )
|
||||
{
|
||||
eState = FCK_TRISTATE_ON ;
|
||||
|
||||
if ( this.RefreshActiveItems )
|
||||
this.RefreshActiveItems( this._Combo, sValue ) ;
|
||||
else
|
||||
{
|
||||
if ( this._LastValue !== sValue)
|
||||
{
|
||||
this._LastValue = sValue ;
|
||||
|
||||
if ( !sValue || sValue.length == 0 )
|
||||
{
|
||||
this._Combo.DeselectAll() ;
|
||||
this._Combo.SetLabel( this.DefaultLabel ) ;
|
||||
}
|
||||
else
|
||||
FCKToolbarSpecialCombo_RefreshActiveItems( this._Combo, sValue ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
eState = FCK_TRISTATE_DISABLED ;
|
||||
// }
|
||||
|
||||
// If there are no state changes then do nothing and return.
|
||||
if ( eState == this.State ) return ;
|
||||
|
||||
if ( eState == FCK_TRISTATE_DISABLED )
|
||||
{
|
||||
this._Combo.DeselectAll() ;
|
||||
this._Combo.SetLabel( '' ) ;
|
||||
}
|
||||
|
||||
// Sets the actual state.
|
||||
this.State = eState ;
|
||||
|
||||
// Updates the graphical state.
|
||||
this._Combo.SetEnabled( eState != FCK_TRISTATE_DISABLED ) ;
|
||||
}
|
||||
|
||||
FCKToolbarSpecialCombo.prototype.Enable = function()
|
||||
{
|
||||
this.RefreshState() ;
|
||||
}
|
||||
|
||||
FCKToolbarSpecialCombo.prototype.Disable = function()
|
||||
{
|
||||
this.State = FCK_TRISTATE_DISABLED ;
|
||||
this._Combo.DeselectAll() ;
|
||||
this._Combo.SetLabel( '' ) ;
|
||||
this._Combo.SetEnabled( false ) ;
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKToolbarPanelButton Class: Handles the Fonts combo selector.
|
||||
*/
|
||||
|
||||
var FCKToolbarStyleCombo = function( tooltip, style )
|
||||
{
|
||||
if ( tooltip === false )
|
||||
return ;
|
||||
|
||||
this.CommandName = 'Style' ;
|
||||
this.Label = this.GetLabel() ;
|
||||
this.Tooltip = tooltip ? tooltip : this.Label ;
|
||||
this.Style = style ? style : FCK_TOOLBARITEM_ICONTEXT ;
|
||||
|
||||
this.DefaultLabel = FCKConfig.DefaultStyleLabel || '' ;
|
||||
}
|
||||
|
||||
// Inherit from FCKToolbarSpecialCombo.
|
||||
FCKToolbarStyleCombo.prototype = new FCKToolbarSpecialCombo ;
|
||||
|
||||
FCKToolbarStyleCombo.prototype.GetLabel = function()
|
||||
{
|
||||
return FCKLang.Style ;
|
||||
}
|
||||
|
||||
FCKToolbarStyleCombo.prototype.GetStyles = function()
|
||||
{
|
||||
var styles = {} ;
|
||||
var allStyles = FCK.ToolbarSet.CurrentInstance.Styles.GetStyles() ;
|
||||
|
||||
for ( var styleName in allStyles )
|
||||
{
|
||||
var style = allStyles[ styleName ] ;
|
||||
if ( !style.IsCore )
|
||||
styles[ styleName ] = style ;
|
||||
}
|
||||
return styles ;
|
||||
}
|
||||
|
||||
FCKToolbarStyleCombo.prototype.CreateItems = function( targetSpecialCombo )
|
||||
{
|
||||
var targetDoc = targetSpecialCombo._Panel.Document ;
|
||||
|
||||
// Add the Editor Area CSS to the panel so the style classes are previewed correctly.
|
||||
FCKTools.AppendStyleSheet( targetDoc, FCKConfig.ToolbarComboPreviewCSS ) ;
|
||||
FCKTools.AppendStyleString( targetDoc, FCKConfig.EditorAreaStyles ) ;
|
||||
targetDoc.body.className += ' ForceBaseFont' ;
|
||||
|
||||
// Add ID and Class to the body.
|
||||
FCKConfig.ApplyBodyAttributes( targetDoc.body ) ;
|
||||
|
||||
// Get the styles list.
|
||||
var styles = this.GetStyles() ;
|
||||
|
||||
for ( var styleName in styles )
|
||||
{
|
||||
var style = styles[ styleName ] ;
|
||||
|
||||
// Object type styles have no preview.
|
||||
var caption = style.GetType() == FCK_STYLE_OBJECT ?
|
||||
styleName :
|
||||
FCKToolbarStyleCombo_BuildPreview( style, style.Label || styleName ) ;
|
||||
|
||||
var item = targetSpecialCombo.AddItem( styleName, caption ) ;
|
||||
|
||||
item.Style = style ;
|
||||
}
|
||||
|
||||
// We must prepare the list before showing it.
|
||||
targetSpecialCombo.OnBeforeClick = this.StyleCombo_OnBeforeClick ;
|
||||
}
|
||||
|
||||
FCKToolbarStyleCombo.prototype.RefreshActiveItems = function( targetSpecialCombo )
|
||||
{
|
||||
var startElement = FCK.ToolbarSet.CurrentInstance.Selection.GetBoundaryParentElement( true ) ;
|
||||
|
||||
if ( startElement )
|
||||
{
|
||||
var path = new FCKElementPath( startElement ) ;
|
||||
var elements = path.Elements ;
|
||||
|
||||
for ( var e = 0 ; e < elements.length ; e++ )
|
||||
{
|
||||
for ( var i in targetSpecialCombo.Items )
|
||||
{
|
||||
var item = targetSpecialCombo.Items[i] ;
|
||||
var style = item.Style ;
|
||||
|
||||
if ( style.CheckElementRemovable( elements[ e ], true ) )
|
||||
{
|
||||
targetSpecialCombo.SetLabel( style.Label || style.Name ) ;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
targetSpecialCombo.SetLabel( this.DefaultLabel ) ;
|
||||
}
|
||||
|
||||
FCKToolbarStyleCombo.prototype.StyleCombo_OnBeforeClick = function( targetSpecialCombo )
|
||||
{
|
||||
// Two things are done here:
|
||||
// - In a control selection, get the element name, so we'll display styles
|
||||
// for that element only.
|
||||
// - Select the styles that are active for the current selection.
|
||||
|
||||
// Clear the current selection.
|
||||
targetSpecialCombo.DeselectAll() ;
|
||||
|
||||
var startElement ;
|
||||
var path ;
|
||||
var tagName ;
|
||||
|
||||
var selection = FCK.ToolbarSet.CurrentInstance.Selection ;
|
||||
|
||||
if ( selection.GetType() == 'Control' )
|
||||
{
|
||||
startElement = selection.GetSelectedElement() ;
|
||||
tagName = startElement.nodeName.toLowerCase() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
startElement = selection.GetBoundaryParentElement( true ) ;
|
||||
path = new FCKElementPath( startElement ) ;
|
||||
}
|
||||
|
||||
for ( var i in targetSpecialCombo.Items )
|
||||
{
|
||||
var item = targetSpecialCombo.Items[i] ;
|
||||
var style = item.Style ;
|
||||
|
||||
if ( ( tagName && style.Element == tagName ) || ( !tagName && style.GetType() != FCK_STYLE_OBJECT ) )
|
||||
{
|
||||
item.style.display = '' ;
|
||||
|
||||
if ( ( path && style.CheckActive( path ) ) || ( !path && style.CheckElementRemovable( startElement, true ) ) )
|
||||
targetSpecialCombo.SelectItem( style.Name ) ;
|
||||
}
|
||||
else
|
||||
item.style.display = 'none' ;
|
||||
}
|
||||
}
|
||||
|
||||
function FCKToolbarStyleCombo_BuildPreview( style, caption )
|
||||
{
|
||||
var styleType = style.GetType() ;
|
||||
var html = [] ;
|
||||
|
||||
if ( styleType == FCK_STYLE_BLOCK )
|
||||
html.push( '<div class="BaseFont">' ) ;
|
||||
|
||||
var elementName = style.Element ;
|
||||
|
||||
// Avoid <bdo> in the preview.
|
||||
if ( elementName == 'bdo' )
|
||||
elementName = 'span' ;
|
||||
|
||||
html = [ '<', elementName ] ;
|
||||
|
||||
// Assign all defined attributes.
|
||||
var attribs = style._StyleDesc.Attributes ;
|
||||
if ( attribs )
|
||||
{
|
||||
for ( var att in attribs )
|
||||
{
|
||||
html.push( ' ', att, '="', style.GetFinalAttributeValue( att ), '"' ) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign the style attribute.
|
||||
if ( style._GetStyleText().length > 0 )
|
||||
html.push( ' style="', style.GetFinalStyleValue(), '"' ) ;
|
||||
|
||||
html.push( '>', caption, '</', elementName, '>' ) ;
|
||||
|
||||
if ( styleType == FCK_STYLE_BLOCK )
|
||||
html.push( '</div>' ) ;
|
||||
|
||||
return html.join( '' ) ;
|
||||
}
|
||||
@@ -0,0 +1,451 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* This class partially implements the W3C DOM Range for browser that don't
|
||||
* support the standards (like IE):
|
||||
* http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html
|
||||
*/
|
||||
|
||||
var FCKW3CRange = function( parentDocument )
|
||||
{
|
||||
this._Document = parentDocument ;
|
||||
|
||||
this.startContainer = null ;
|
||||
this.startOffset = null ;
|
||||
this.endContainer = null ;
|
||||
this.endOffset = null ;
|
||||
this.collapsed = true ;
|
||||
}
|
||||
|
||||
FCKW3CRange.CreateRange = function( parentDocument )
|
||||
{
|
||||
// We could opt to use the Range implementation of the browsers. The problem
|
||||
// is that every browser have different bugs on their implementations,
|
||||
// mostly related to different interpretations of the W3C specifications.
|
||||
// So, for now, let's use our implementation and pray for browsers fixings
|
||||
// soon. Otherwise will go crazy on trying to find out workarounds.
|
||||
/*
|
||||
// Get the browser implementation of the range, if available.
|
||||
if ( parentDocument.createRange )
|
||||
{
|
||||
var range = parentDocument.createRange() ;
|
||||
if ( typeof( range.startContainer ) != 'undefined' )
|
||||
return range ;
|
||||
}
|
||||
*/
|
||||
return new FCKW3CRange( parentDocument ) ;
|
||||
}
|
||||
|
||||
FCKW3CRange.CreateFromRange = function( parentDocument, sourceRange )
|
||||
{
|
||||
var range = FCKW3CRange.CreateRange( parentDocument ) ;
|
||||
range.setStart( sourceRange.startContainer, sourceRange.startOffset ) ;
|
||||
range.setEnd( sourceRange.endContainer, sourceRange.endOffset ) ;
|
||||
return range ;
|
||||
}
|
||||
|
||||
FCKW3CRange.prototype =
|
||||
{
|
||||
|
||||
_UpdateCollapsed : function()
|
||||
{
|
||||
this.collapsed = ( this.startContainer == this.endContainer && this.startOffset == this.endOffset ) ;
|
||||
},
|
||||
|
||||
// W3C requires a check for the new position. If it is after the end
|
||||
// boundary, the range should be collapsed to the new start. It seams we
|
||||
// will not need this check for our use of this class so we can ignore it for now.
|
||||
setStart : function( refNode, offset )
|
||||
{
|
||||
this.startContainer = refNode ;
|
||||
this.startOffset = offset ;
|
||||
|
||||
if ( !this.endContainer )
|
||||
{
|
||||
this.endContainer = refNode ;
|
||||
this.endOffset = offset ;
|
||||
}
|
||||
|
||||
this._UpdateCollapsed() ;
|
||||
},
|
||||
|
||||
// W3C requires a check for the new position. If it is before the start
|
||||
// boundary, the range should be collapsed to the new end. It seams we
|
||||
// will not need this check for our use of this class so we can ignore it for now.
|
||||
setEnd : function( refNode, offset )
|
||||
{
|
||||
this.endContainer = refNode ;
|
||||
this.endOffset = offset ;
|
||||
|
||||
if ( !this.startContainer )
|
||||
{
|
||||
this.startContainer = refNode ;
|
||||
this.startOffset = offset ;
|
||||
}
|
||||
|
||||
this._UpdateCollapsed() ;
|
||||
},
|
||||
|
||||
setStartAfter : function( refNode )
|
||||
{
|
||||
this.setStart( refNode.parentNode, FCKDomTools.GetIndexOf( refNode ) + 1 ) ;
|
||||
},
|
||||
|
||||
setStartBefore : function( refNode )
|
||||
{
|
||||
this.setStart( refNode.parentNode, FCKDomTools.GetIndexOf( refNode ) ) ;
|
||||
},
|
||||
|
||||
setEndAfter : function( refNode )
|
||||
{
|
||||
this.setEnd( refNode.parentNode, FCKDomTools.GetIndexOf( refNode ) + 1 ) ;
|
||||
},
|
||||
|
||||
setEndBefore : function( refNode )
|
||||
{
|
||||
this.setEnd( refNode.parentNode, FCKDomTools.GetIndexOf( refNode ) ) ;
|
||||
},
|
||||
|
||||
collapse : function( toStart )
|
||||
{
|
||||
if ( toStart )
|
||||
{
|
||||
this.endContainer = this.startContainer ;
|
||||
this.endOffset = this.startOffset ;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.startContainer = this.endContainer ;
|
||||
this.startOffset = this.endOffset ;
|
||||
}
|
||||
|
||||
this.collapsed = true ;
|
||||
},
|
||||
|
||||
selectNodeContents : function( refNode )
|
||||
{
|
||||
this.setStart( refNode, 0 ) ;
|
||||
this.setEnd( refNode, refNode.nodeType == 3 ? refNode.data.length : refNode.childNodes.length ) ;
|
||||
},
|
||||
|
||||
insertNode : function( newNode )
|
||||
{
|
||||
var startContainer = this.startContainer ;
|
||||
var startOffset = this.startOffset ;
|
||||
|
||||
// If we are in a text node.
|
||||
if ( startContainer.nodeType == 3 )
|
||||
{
|
||||
startContainer.splitText( startOffset ) ;
|
||||
|
||||
// Check if it is necessary to update the end boundary.
|
||||
if ( startContainer == this.endContainer )
|
||||
this.setEnd( startContainer.nextSibling, this.endOffset - this.startOffset ) ;
|
||||
|
||||
// Insert the new node it after the text node.
|
||||
FCKDomTools.InsertAfterNode( startContainer, newNode ) ;
|
||||
|
||||
return ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Simply insert the new node before the current start node.
|
||||
startContainer.insertBefore( newNode, startContainer.childNodes[ startOffset ] || null ) ;
|
||||
|
||||
// Check if it is necessary to update the end boundary.
|
||||
if ( startContainer == this.endContainer )
|
||||
{
|
||||
this.endOffset++ ;
|
||||
this.collapsed = false ;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
deleteContents : function()
|
||||
{
|
||||
if ( this.collapsed )
|
||||
return ;
|
||||
|
||||
this._ExecContentsAction( 0 ) ;
|
||||
},
|
||||
|
||||
extractContents : function()
|
||||
{
|
||||
var docFrag = new FCKDocumentFragment( this._Document ) ;
|
||||
|
||||
if ( !this.collapsed )
|
||||
this._ExecContentsAction( 1, docFrag ) ;
|
||||
|
||||
return docFrag ;
|
||||
},
|
||||
|
||||
// The selection may be lost when cloning (due to the splitText() call).
|
||||
cloneContents : function()
|
||||
{
|
||||
var docFrag = new FCKDocumentFragment( this._Document ) ;
|
||||
|
||||
if ( !this.collapsed )
|
||||
this._ExecContentsAction( 2, docFrag ) ;
|
||||
|
||||
return docFrag ;
|
||||
},
|
||||
|
||||
_ExecContentsAction : function( action, docFrag )
|
||||
{
|
||||
var startNode = this.startContainer ;
|
||||
var endNode = this.endContainer ;
|
||||
|
||||
var startOffset = this.startOffset ;
|
||||
var endOffset = this.endOffset ;
|
||||
|
||||
var removeStartNode = false ;
|
||||
var removeEndNode = false ;
|
||||
|
||||
// Check the start and end nodes and make the necessary removals or changes.
|
||||
|
||||
// Start from the end, otherwise DOM mutations (splitText) made in the
|
||||
// start boundary may interfere on the results here.
|
||||
|
||||
// For text containers, we must simply split the node and point to the
|
||||
// second part. The removal will be handled by the rest of the code .
|
||||
if ( endNode.nodeType == 3 )
|
||||
endNode = endNode.splitText( endOffset ) ;
|
||||
else
|
||||
{
|
||||
// If the end container has children and the offset is pointing
|
||||
// to a child, then we should start from it.
|
||||
if ( endNode.childNodes.length > 0 )
|
||||
{
|
||||
// If the offset points after the last node.
|
||||
if ( endOffset > endNode.childNodes.length - 1 )
|
||||
{
|
||||
// Let's create a temporary node and mark it for removal.
|
||||
endNode = FCKDomTools.InsertAfterNode( endNode.lastChild, this._Document.createTextNode('') ) ;
|
||||
removeEndNode = true ;
|
||||
}
|
||||
else
|
||||
endNode = endNode.childNodes[ endOffset ] ;
|
||||
}
|
||||
}
|
||||
|
||||
// For text containers, we must simply split the node. The removal will
|
||||
// be handled by the rest of the code .
|
||||
if ( startNode.nodeType == 3 )
|
||||
{
|
||||
startNode.splitText( startOffset ) ;
|
||||
|
||||
// In cases the end node is the same as the start node, the above
|
||||
// splitting will also split the end, so me must move the end to
|
||||
// the second part of the split.
|
||||
if ( startNode == endNode )
|
||||
endNode = startNode.nextSibling ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the start container has children and the offset is pointing
|
||||
// to a child, then we should start from its previous sibling.
|
||||
|
||||
// If the offset points to the first node, we don't have a
|
||||
// sibling, so let's use the first one, but mark it for removal.
|
||||
if ( startOffset == 0 )
|
||||
{
|
||||
// Let's create a temporary node and mark it for removal.
|
||||
startNode = startNode.insertBefore( this._Document.createTextNode(''), startNode.firstChild ) ;
|
||||
removeStartNode = true ;
|
||||
}
|
||||
else if ( startOffset > startNode.childNodes.length - 1 )
|
||||
{
|
||||
// Let's create a temporary node and mark it for removal.
|
||||
startNode = startNode.appendChild( this._Document.createTextNode('') ) ;
|
||||
removeStartNode = true ;
|
||||
}
|
||||
else
|
||||
startNode = startNode.childNodes[ startOffset ].previousSibling ;
|
||||
}
|
||||
|
||||
// Get the parent nodes tree for the start and end boundaries.
|
||||
var startParents = FCKDomTools.GetParents( startNode ) ;
|
||||
var endParents = FCKDomTools.GetParents( endNode ) ;
|
||||
|
||||
// Compare them, to find the top most siblings.
|
||||
var i, topStart, topEnd ;
|
||||
|
||||
for ( i = 0 ; i < startParents.length ; i++ )
|
||||
{
|
||||
topStart = startParents[i] ;
|
||||
topEnd = endParents[i] ;
|
||||
|
||||
// The compared nodes will match until we find the top most
|
||||
// siblings (different nodes that have the same parent).
|
||||
// "i" will hold the index in the parents array for the top
|
||||
// most element.
|
||||
if ( topStart != topEnd )
|
||||
break ;
|
||||
}
|
||||
|
||||
var clone, levelStartNode, levelClone, currentNode, currentSibling ;
|
||||
|
||||
if ( docFrag )
|
||||
clone = docFrag.RootNode ;
|
||||
|
||||
// Remove all successive sibling nodes for every node in the
|
||||
// startParents tree.
|
||||
for ( var j = i ; j < startParents.length ; j++ )
|
||||
{
|
||||
levelStartNode = startParents[j] ;
|
||||
|
||||
// For Extract and Clone, we must clone this level.
|
||||
if ( clone && levelStartNode != startNode ) // action = 0 = Delete
|
||||
levelClone = clone.appendChild( levelStartNode.cloneNode( levelStartNode == startNode ) ) ;
|
||||
|
||||
currentNode = levelStartNode.nextSibling ;
|
||||
|
||||
while( currentNode )
|
||||
{
|
||||
// Stop processing when the current node matches a node in the
|
||||
// endParents tree or if it is the endNode.
|
||||
if ( currentNode == endParents[j] || currentNode == endNode )
|
||||
break ;
|
||||
|
||||
// Cache the next sibling.
|
||||
currentSibling = currentNode.nextSibling ;
|
||||
|
||||
// If cloning, just clone it.
|
||||
if ( action == 2 ) // 2 = Clone
|
||||
clone.appendChild( currentNode.cloneNode( true ) ) ;
|
||||
else
|
||||
{
|
||||
// Both Delete and Extract will remove the node.
|
||||
currentNode.parentNode.removeChild( currentNode ) ;
|
||||
|
||||
// When Extracting, move the removed node to the docFrag.
|
||||
if ( action == 1 ) // 1 = Extract
|
||||
clone.appendChild( currentNode ) ;
|
||||
}
|
||||
|
||||
currentNode = currentSibling ;
|
||||
}
|
||||
|
||||
if ( clone )
|
||||
clone = levelClone ;
|
||||
}
|
||||
|
||||
if ( docFrag )
|
||||
clone = docFrag.RootNode ;
|
||||
|
||||
// Remove all previous sibling nodes for every node in the
|
||||
// endParents tree.
|
||||
for ( var k = i ; k < endParents.length ; k++ )
|
||||
{
|
||||
levelStartNode = endParents[k] ;
|
||||
|
||||
// For Extract and Clone, we must clone this level.
|
||||
if ( action > 0 && levelStartNode != endNode ) // action = 0 = Delete
|
||||
levelClone = clone.appendChild( levelStartNode.cloneNode( levelStartNode == endNode ) ) ;
|
||||
|
||||
// The processing of siblings may have already been done by the parent.
|
||||
if ( !startParents[k] || levelStartNode.parentNode != startParents[k].parentNode )
|
||||
{
|
||||
currentNode = levelStartNode.previousSibling ;
|
||||
|
||||
while( currentNode )
|
||||
{
|
||||
// Stop processing when the current node matches a node in the
|
||||
// startParents tree or if it is the startNode.
|
||||
if ( currentNode == startParents[k] || currentNode == startNode )
|
||||
break ;
|
||||
|
||||
// Cache the next sibling.
|
||||
currentSibling = currentNode.previousSibling ;
|
||||
|
||||
// If cloning, just clone it.
|
||||
if ( action == 2 ) // 2 = Clone
|
||||
clone.insertBefore( currentNode.cloneNode( true ), clone.firstChild ) ;
|
||||
else
|
||||
{
|
||||
// Both Delete and Extract will remove the node.
|
||||
currentNode.parentNode.removeChild( currentNode ) ;
|
||||
|
||||
// When Extracting, mode the removed node to the docFrag.
|
||||
if ( action == 1 ) // 1 = Extract
|
||||
clone.insertBefore( currentNode, clone.firstChild ) ;
|
||||
}
|
||||
|
||||
currentNode = currentSibling ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( clone )
|
||||
clone = levelClone ;
|
||||
}
|
||||
|
||||
if ( action == 2 ) // 2 = Clone.
|
||||
{
|
||||
// No changes in the DOM should be done, so fix the split text (if any).
|
||||
|
||||
var startTextNode = this.startContainer ;
|
||||
if ( startTextNode.nodeType == 3 )
|
||||
{
|
||||
startTextNode.data += startTextNode.nextSibling.data ;
|
||||
startTextNode.parentNode.removeChild( startTextNode.nextSibling ) ;
|
||||
}
|
||||
|
||||
var endTextNode = this.endContainer ;
|
||||
if ( endTextNode.nodeType == 3 && endTextNode.nextSibling )
|
||||
{
|
||||
endTextNode.data += endTextNode.nextSibling.data ;
|
||||
endTextNode.parentNode.removeChild( endTextNode.nextSibling ) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Collapse the range.
|
||||
|
||||
// If a node has been partially selected, collapse the range between
|
||||
// topStart and topEnd. Otherwise, simply collapse it to the start. (W3C specs).
|
||||
if ( topStart && topEnd && ( startNode.parentNode != topStart.parentNode || endNode.parentNode != topEnd.parentNode ) )
|
||||
{
|
||||
var endIndex = FCKDomTools.GetIndexOf( topEnd ) ;
|
||||
|
||||
// If the start node is to be removed, we must correct the
|
||||
// index to reflect the removal.
|
||||
if ( removeStartNode && topEnd.parentNode == startNode.parentNode )
|
||||
endIndex-- ;
|
||||
|
||||
this.setStart( topEnd.parentNode, endIndex ) ;
|
||||
}
|
||||
|
||||
// Collapse it to the start.
|
||||
this.collapse( true ) ;
|
||||
}
|
||||
|
||||
// Cleanup any marked node.
|
||||
if( removeStartNode )
|
||||
startNode.parentNode.removeChild( startNode ) ;
|
||||
|
||||
if( removeEndNode && endNode.parentNode )
|
||||
endNode.parentNode.removeChild( endNode ) ;
|
||||
},
|
||||
|
||||
cloneRange : function()
|
||||
{
|
||||
return FCKW3CRange.CreateFromRange( this._Document, this ) ;
|
||||
}
|
||||
} ;
|
||||
108
_cubecart/CubeCart-4.3.0/admin/includes/rte/editor/_source/classes/fckxml.js
Executable file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKXml Class: class to load and manipulate XML files.
|
||||
* (IE specific implementation)
|
||||
*/
|
||||
|
||||
var FCKXml = function()
|
||||
{
|
||||
this.Error = false ;
|
||||
}
|
||||
|
||||
FCKXml.GetAttribute = function( node, attName, defaultValue )
|
||||
{
|
||||
var attNode = node.attributes.getNamedItem( attName ) ;
|
||||
return attNode ? attNode.value : defaultValue ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a XML element node in a JavaScript object. Attributes defined for
|
||||
* the element will be available as properties, as long as child element
|
||||
* nodes, but the later will generate arrays with property names prefixed with "$".
|
||||
*
|
||||
* For example, the following XML element:
|
||||
*
|
||||
* <SomeNode name="Test" key="2">
|
||||
* <MyChild id="10">
|
||||
* <OtherLevel name="Level 3" />
|
||||
* </MyChild>
|
||||
* <MyChild id="25" />
|
||||
* <AnotherChild price="499" />
|
||||
* </SomeNode>
|
||||
*
|
||||
* ... results in the following object:
|
||||
*
|
||||
* {
|
||||
* name : "Test",
|
||||
* key : "2",
|
||||
* $MyChild :
|
||||
* [
|
||||
* {
|
||||
* id : "10",
|
||||
* $OtherLevel :
|
||||
* {
|
||||
* name : "Level 3"
|
||||
* }
|
||||
* },
|
||||
* {
|
||||
* id : "25"
|
||||
* }
|
||||
* ],
|
||||
* $AnotherChild :
|
||||
* [
|
||||
* {
|
||||
* price : "499"
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
FCKXml.TransformToObject = function( element )
|
||||
{
|
||||
if ( !element )
|
||||
return null ;
|
||||
|
||||
var obj = {} ;
|
||||
|
||||
var attributes = element.attributes ;
|
||||
for ( var i = 0 ; i < attributes.length ; i++ )
|
||||
{
|
||||
var att = attributes[i] ;
|
||||
obj[ att.name ] = att.value ;
|
||||
}
|
||||
|
||||
var childNodes = element.childNodes ;
|
||||
for ( i = 0 ; i < childNodes.length ; i++ )
|
||||
{
|
||||
var child = childNodes[i] ;
|
||||
|
||||
if ( child.nodeType == 1 )
|
||||
{
|
||||
var childName = '$' + child.nodeName ;
|
||||
var childList = obj[ childName ] ;
|
||||
if ( !childList )
|
||||
childList = obj[ childName ] = [] ;
|
||||
|
||||
childList.push( this.TransformToObject( child ) ) ;
|
||||
}
|
||||
}
|
||||
|
||||
return obj ;
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKXml Class: class to load and manipulate XML files.
|
||||
*/
|
||||
|
||||
FCKXml.prototype =
|
||||
{
|
||||
LoadUrl : function( urlToCall )
|
||||
{
|
||||
this.Error = false ;
|
||||
|
||||
var oXml ;
|
||||
var oXmlHttp = FCKTools.CreateXmlObject( 'XmlHttp' ) ;
|
||||
oXmlHttp.open( 'GET', urlToCall, false ) ;
|
||||
oXmlHttp.send( null ) ;
|
||||
|
||||
if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 || ( oXmlHttp.status == 0 && oXmlHttp.readyState == 4 ) )
|
||||
{
|
||||
oXml = oXmlHttp.responseXML ;
|
||||
// #1426: Fallback if responseXML isn't set for some
|
||||
// reason (e.g. improperly configured web server)
|
||||
if ( !oXml )
|
||||
oXml = (new DOMParser()).parseFromString( oXmlHttp.responseText, 'text/xml' ) ;
|
||||
}
|
||||
else
|
||||
oXml = null ;
|
||||
|
||||
if ( oXml )
|
||||
{
|
||||
// Try to access something on it.
|
||||
try
|
||||
{
|
||||
var test = oXml.firstChild ;
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// If document.domain has been changed (#123), we'll have a security
|
||||
// error at this point. The workaround here is parsing the responseText:
|
||||
// http://alexander.kirk.at/2006/07/27/firefox-15-xmlhttprequest-reqresponsexml-and-documentdomain/
|
||||
oXml = (new DOMParser()).parseFromString( oXmlHttp.responseText, 'text/xml' ) ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !oXml || !oXml.firstChild )
|
||||
{
|
||||
this.Error = true ;
|
||||
if ( window.confirm( 'Error loading "' + urlToCall + '" (HTTP Status: ' + oXmlHttp.status + ').\r\nDo you want to see the server response dump?' ) )
|
||||
alert( oXmlHttp.responseText ) ;
|
||||
}
|
||||
|
||||
this.DOMDocument = oXml ;
|
||||
},
|
||||
|
||||
SelectNodes : function( xpath, contextNode )
|
||||
{
|
||||
if ( this.Error )
|
||||
return new Array() ;
|
||||
|
||||
var aNodeArray = new Array();
|
||||
|
||||
var xPathResult = this.DOMDocument.evaluate( xpath, contextNode ? contextNode : this.DOMDocument,
|
||||
this.DOMDocument.createNSResolver(this.DOMDocument.documentElement), XPathResult.ORDERED_NODE_ITERATOR_TYPE, null) ;
|
||||
if ( xPathResult )
|
||||
{
|
||||
var oNode = xPathResult.iterateNext() ;
|
||||
while( oNode )
|
||||
{
|
||||
aNodeArray[aNodeArray.length] = oNode ;
|
||||
oNode = xPathResult.iterateNext();
|
||||
}
|
||||
}
|
||||
return aNodeArray ;
|
||||
},
|
||||
|
||||
SelectSingleNode : function( xpath, contextNode )
|
||||
{
|
||||
if ( this.Error )
|
||||
return null ;
|
||||
|
||||
var xPathResult = this.DOMDocument.evaluate( xpath, contextNode ? contextNode : this.DOMDocument,
|
||||
this.DOMDocument.createNSResolver(this.DOMDocument.documentElement), 9, null);
|
||||
|
||||
if ( xPathResult && xPathResult.singleNodeValue )
|
||||
return xPathResult.singleNodeValue ;
|
||||
else
|
||||
return null ;
|
||||
}
|
||||
} ;
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKXml Class: class to load and manipulate XML files.
|
||||
* (IE specific implementation)
|
||||
*/
|
||||
|
||||
FCKXml.prototype =
|
||||
{
|
||||
LoadUrl : function( urlToCall )
|
||||
{
|
||||
this.Error = false ;
|
||||
|
||||
var oXmlHttp = FCKTools.CreateXmlObject( 'XmlHttp' ) ;
|
||||
|
||||
if ( !oXmlHttp )
|
||||
{
|
||||
this.Error = true ;
|
||||
return ;
|
||||
}
|
||||
|
||||
oXmlHttp.open( "GET", urlToCall, false ) ;
|
||||
|
||||
oXmlHttp.send( null ) ;
|
||||
|
||||
if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 || ( oXmlHttp.status == 0 && oXmlHttp.readyState == 4 ) )
|
||||
{
|
||||
this.DOMDocument = oXmlHttp.responseXML ;
|
||||
|
||||
// #1426: Fallback if responseXML isn't set for some
|
||||
// reason (e.g. improperly configured web server)
|
||||
if ( !this.DOMDocument || this.DOMDocument.firstChild == null )
|
||||
{
|
||||
this.DOMDocument = FCKTools.CreateXmlObject( 'DOMDocument' ) ;
|
||||
this.DOMDocument.async = false ;
|
||||
this.DOMDocument.resolveExternals = false ;
|
||||
this.DOMDocument.loadXML( oXmlHttp.responseText ) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.DOMDocument = null ;
|
||||
}
|
||||
|
||||
if ( this.DOMDocument == null || this.DOMDocument.firstChild == null )
|
||||
{
|
||||
this.Error = true ;
|
||||
if (window.confirm( 'Error loading "' + urlToCall + '"\r\nDo you want to see more info?' ) )
|
||||
alert( 'URL requested: "' + urlToCall + '"\r\n' +
|
||||
'Server response:\r\nStatus: ' + oXmlHttp.status + '\r\n' +
|
||||
'Response text:\r\n' + oXmlHttp.responseText ) ;
|
||||
}
|
||||
},
|
||||
|
||||
SelectNodes : function( xpath, contextNode )
|
||||
{
|
||||
if ( this.Error )
|
||||
return new Array() ;
|
||||
|
||||
if ( contextNode )
|
||||
return contextNode.selectNodes( xpath ) ;
|
||||
else
|
||||
return this.DOMDocument.selectNodes( xpath ) ;
|
||||
},
|
||||
|
||||
SelectSingleNode : function( xpath, contextNode )
|
||||
{
|
||||
if ( this.Error )
|
||||
return null ;
|
||||
|
||||
if ( contextNode )
|
||||
return contextNode.selectSingleNode( xpath ) ;
|
||||
else
|
||||
return this.DOMDocument.selectSingleNode( xpath ) ;
|
||||
}
|
||||
} ;
|
||||
@@ -0,0 +1,634 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Definition of other commands that are not available internaly in the
|
||||
* browser (see FCKNamedCommand).
|
||||
*/
|
||||
|
||||
// ### General Dialog Box Commands.
|
||||
var FCKDialogCommand = function( name, title, url, width, height, getStateFunction, getStateParam, customValue )
|
||||
{
|
||||
this.Name = name ;
|
||||
this.Title = title ;
|
||||
this.Url = url ;
|
||||
this.Width = width ;
|
||||
this.Height = height ;
|
||||
this.CustomValue = customValue ;
|
||||
|
||||
this.GetStateFunction = getStateFunction ;
|
||||
this.GetStateParam = getStateParam ;
|
||||
|
||||
this.Resizable = false ;
|
||||
}
|
||||
|
||||
FCKDialogCommand.prototype.Execute = function()
|
||||
{
|
||||
FCKDialog.OpenDialog( 'FCKDialog_' + this.Name , this.Title, this.Url, this.Width, this.Height, this.CustomValue, null, this.Resizable ) ;
|
||||
}
|
||||
|
||||
FCKDialogCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( this.GetStateFunction )
|
||||
return this.GetStateFunction( this.GetStateParam ) ;
|
||||
else
|
||||
return FCK.EditMode == FCK_EDITMODE_WYSIWYG ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
|
||||
}
|
||||
|
||||
// Generic Undefined command (usually used when a command is under development).
|
||||
var FCKUndefinedCommand = function()
|
||||
{
|
||||
this.Name = 'Undefined' ;
|
||||
}
|
||||
|
||||
FCKUndefinedCommand.prototype.Execute = function()
|
||||
{
|
||||
alert( FCKLang.NotImplemented ) ;
|
||||
}
|
||||
|
||||
FCKUndefinedCommand.prototype.GetState = function()
|
||||
{
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
|
||||
|
||||
// ### FormatBlock
|
||||
var FCKFormatBlockCommand = function()
|
||||
{}
|
||||
|
||||
FCKFormatBlockCommand.prototype =
|
||||
{
|
||||
Name : 'FormatBlock',
|
||||
|
||||
Execute : FCKStyleCommand.prototype.Execute,
|
||||
|
||||
GetState : function()
|
||||
{
|
||||
return FCK.EditorDocument ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
|
||||
}
|
||||
};
|
||||
|
||||
// ### FontName
|
||||
|
||||
var FCKFontNameCommand = function()
|
||||
{}
|
||||
|
||||
FCKFontNameCommand.prototype =
|
||||
{
|
||||
Name : 'FontName',
|
||||
Execute : FCKStyleCommand.prototype.Execute,
|
||||
GetState : FCKFormatBlockCommand.prototype.GetState
|
||||
};
|
||||
|
||||
// ### FontSize
|
||||
var FCKFontSizeCommand = function()
|
||||
{}
|
||||
|
||||
FCKFontSizeCommand.prototype =
|
||||
{
|
||||
Name : 'FontSize',
|
||||
Execute : FCKStyleCommand.prototype.Execute,
|
||||
GetState : FCKFormatBlockCommand.prototype.GetState
|
||||
};
|
||||
|
||||
// ### Preview
|
||||
var FCKPreviewCommand = function()
|
||||
{
|
||||
this.Name = 'Preview' ;
|
||||
}
|
||||
|
||||
FCKPreviewCommand.prototype.Execute = function()
|
||||
{
|
||||
FCK.Preview() ;
|
||||
}
|
||||
|
||||
FCKPreviewCommand.prototype.GetState = function()
|
||||
{
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
|
||||
// ### Save
|
||||
var FCKSaveCommand = function()
|
||||
{
|
||||
this.Name = 'Save' ;
|
||||
}
|
||||
|
||||
FCKSaveCommand.prototype.Execute = function()
|
||||
{
|
||||
// Get the linked field form.
|
||||
var oForm = FCK.GetParentForm() ;
|
||||
|
||||
if ( typeof( oForm.onsubmit ) == 'function' )
|
||||
{
|
||||
var bRet = oForm.onsubmit() ;
|
||||
if ( bRet != null && bRet === false )
|
||||
return ;
|
||||
}
|
||||
|
||||
// Submit the form.
|
||||
// If there's a button named "submit" then the form.submit() function is masked and
|
||||
// can't be called in Mozilla, so we call the click() method of that button.
|
||||
if ( typeof( oForm.submit ) == 'function' )
|
||||
oForm.submit() ;
|
||||
else
|
||||
oForm.submit.click() ;
|
||||
}
|
||||
|
||||
FCKSaveCommand.prototype.GetState = function()
|
||||
{
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
|
||||
// ### NewPage
|
||||
var FCKNewPageCommand = function()
|
||||
{
|
||||
this.Name = 'NewPage' ;
|
||||
}
|
||||
|
||||
FCKNewPageCommand.prototype.Execute = function()
|
||||
{
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
FCK.SetData( '' ) ;
|
||||
FCKUndo.Typing = true ;
|
||||
FCK.Focus() ;
|
||||
}
|
||||
|
||||
FCKNewPageCommand.prototype.GetState = function()
|
||||
{
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
|
||||
// ### Source button
|
||||
var FCKSourceCommand = function()
|
||||
{
|
||||
this.Name = 'Source' ;
|
||||
}
|
||||
|
||||
FCKSourceCommand.prototype.Execute = function()
|
||||
{
|
||||
if ( FCKConfig.SourcePopup ) // Until v2.2, it was mandatory for FCKBrowserInfo.IsGecko.
|
||||
{
|
||||
var iWidth = FCKConfig.ScreenWidth * 0.65 ;
|
||||
var iHeight = FCKConfig.ScreenHeight * 0.65 ;
|
||||
FCKDialog.OpenDialog( 'FCKDialog_Source', FCKLang.Source, 'dialog/fck_source.html', iWidth, iHeight, null, null, true ) ;
|
||||
}
|
||||
else
|
||||
FCK.SwitchEditMode() ;
|
||||
}
|
||||
|
||||
FCKSourceCommand.prototype.GetState = function()
|
||||
{
|
||||
return ( FCK.EditMode == FCK_EDITMODE_WYSIWYG ? FCK_TRISTATE_OFF : FCK_TRISTATE_ON ) ;
|
||||
}
|
||||
|
||||
// ### Undo
|
||||
var FCKUndoCommand = function()
|
||||
{
|
||||
this.Name = 'Undo' ;
|
||||
}
|
||||
|
||||
FCKUndoCommand.prototype.Execute = function()
|
||||
{
|
||||
FCKUndo.Undo() ;
|
||||
}
|
||||
|
||||
FCKUndoCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return ( FCKUndo.CheckUndoState() ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ) ;
|
||||
}
|
||||
|
||||
// ### Redo
|
||||
var FCKRedoCommand = function()
|
||||
{
|
||||
this.Name = 'Redo' ;
|
||||
}
|
||||
|
||||
FCKRedoCommand.prototype.Execute = function()
|
||||
{
|
||||
FCKUndo.Redo() ;
|
||||
}
|
||||
|
||||
FCKRedoCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return ( FCKUndo.CheckRedoState() ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ) ;
|
||||
}
|
||||
|
||||
// ### Page Break
|
||||
var FCKPageBreakCommand = function()
|
||||
{
|
||||
this.Name = 'PageBreak' ;
|
||||
}
|
||||
|
||||
FCKPageBreakCommand.prototype.Execute = function()
|
||||
{
|
||||
// Take an undo snapshot before changing the document
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
// var e = FCK.EditorDocument.createElement( 'CENTER' ) ;
|
||||
// e.style.pageBreakAfter = 'always' ;
|
||||
|
||||
// Tidy was removing the empty CENTER tags, so the following solution has
|
||||
// been found. It also validates correctly as XHTML 1.0 Strict.
|
||||
var e = FCK.EditorDocument.createElement( 'DIV' ) ;
|
||||
e.style.pageBreakAfter = 'always' ;
|
||||
e.innerHTML = '<span style="DISPLAY:none"> </span>' ;
|
||||
|
||||
var oFakeImage = FCKDocumentProcessor_CreateFakeImage( 'FCK__PageBreak', e ) ;
|
||||
var oRange = new FCKDomRange( FCK.EditorWindow ) ;
|
||||
oRange.MoveToSelection() ;
|
||||
var oSplitInfo = oRange.SplitBlock() ;
|
||||
oRange.InsertNode( oFakeImage ) ;
|
||||
|
||||
FCK.Events.FireEvent( 'OnSelectionChange' ) ;
|
||||
}
|
||||
|
||||
FCKPageBreakCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return 0 ; // FCK_TRISTATE_OFF
|
||||
}
|
||||
|
||||
// FCKUnlinkCommand - by Johnny Egeland (johnny@coretrek.com)
|
||||
var FCKUnlinkCommand = function()
|
||||
{
|
||||
this.Name = 'Unlink' ;
|
||||
}
|
||||
|
||||
FCKUnlinkCommand.prototype.Execute = function()
|
||||
{
|
||||
// Take an undo snapshot before changing the document
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
if ( FCKBrowserInfo.IsGeckoLike )
|
||||
{
|
||||
var oLink = FCK.Selection.MoveToAncestorNode( 'A' ) ;
|
||||
// The unlink command can generate a span in Firefox, so let's do it our way. See #430
|
||||
if ( oLink )
|
||||
FCKTools.RemoveOuterTags( oLink ) ;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
FCK.ExecuteNamedCommand( this.Name ) ;
|
||||
}
|
||||
|
||||
FCKUnlinkCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
var state = FCK.GetNamedCommandState( this.Name ) ;
|
||||
|
||||
// Check that it isn't an anchor
|
||||
if ( state == FCK_TRISTATE_OFF && FCK.EditMode == FCK_EDITMODE_WYSIWYG )
|
||||
{
|
||||
var oLink = FCKSelection.MoveToAncestorNode( 'A' ) ;
|
||||
var bIsAnchor = ( oLink && oLink.name.length > 0 && oLink.href.length == 0 ) ;
|
||||
if ( bIsAnchor )
|
||||
state = FCK_TRISTATE_DISABLED ;
|
||||
}
|
||||
|
||||
return state ;
|
||||
}
|
||||
|
||||
FCKVisitLinkCommand = function()
|
||||
{
|
||||
this.Name = 'VisitLink';
|
||||
}
|
||||
FCKVisitLinkCommand.prototype =
|
||||
{
|
||||
GetState : function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
var state = FCK.GetNamedCommandState( 'Unlink' ) ;
|
||||
|
||||
if ( state == FCK_TRISTATE_OFF )
|
||||
{
|
||||
var el = FCKSelection.MoveToAncestorNode( 'A' ) ;
|
||||
if ( !el.href )
|
||||
state = FCK_TRISTATE_DISABLED ;
|
||||
}
|
||||
|
||||
return state ;
|
||||
},
|
||||
|
||||
Execute : function()
|
||||
{
|
||||
var el = FCKSelection.MoveToAncestorNode( 'A' ) ;
|
||||
var url = el.getAttribute( '_fcksavedurl' ) || el.getAttribute( 'href', 2 ) ;
|
||||
|
||||
// Check if it's a full URL.
|
||||
// If not full URL, we'll need to apply the BaseHref setting.
|
||||
if ( ! /:\/\//.test( url ) )
|
||||
{
|
||||
var baseHref = FCKConfig.BaseHref ;
|
||||
var parentWindow = FCK.GetInstanceObject( 'parent' ) ;
|
||||
if ( !baseHref )
|
||||
{
|
||||
baseHref = parentWindow.document.location.href ;
|
||||
baseHref = baseHref.substring( 0, baseHref.lastIndexOf( '/' ) + 1 ) ;
|
||||
}
|
||||
|
||||
if ( /^\//.test( url ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
baseHref = baseHref.match( /^.*:\/\/+[^\/]+/ )[0] ;
|
||||
}
|
||||
catch ( e )
|
||||
{
|
||||
baseHref = parentWindow.document.location.protocol + '://' + parentWindow.parent.document.location.host ;
|
||||
}
|
||||
}
|
||||
|
||||
url = baseHref + url ;
|
||||
}
|
||||
|
||||
if ( !window.open( url, '_blank' ) )
|
||||
alert( FCKLang.VisitLinkBlocked ) ;
|
||||
}
|
||||
} ;
|
||||
|
||||
// FCKSelectAllCommand
|
||||
var FCKSelectAllCommand = function()
|
||||
{
|
||||
this.Name = 'SelectAll' ;
|
||||
}
|
||||
|
||||
FCKSelectAllCommand.prototype.Execute = function()
|
||||
{
|
||||
if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )
|
||||
{
|
||||
FCK.ExecuteNamedCommand( 'SelectAll' ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Select the contents of the textarea
|
||||
var textarea = FCK.EditingArea.Textarea ;
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
{
|
||||
textarea.createTextRange().execCommand( 'SelectAll' ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
textarea.selectionStart = 0 ;
|
||||
textarea.selectionEnd = textarea.value.length ;
|
||||
}
|
||||
textarea.focus() ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKSelectAllCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
|
||||
// FCKPasteCommand
|
||||
var FCKPasteCommand = function()
|
||||
{
|
||||
this.Name = 'Paste' ;
|
||||
}
|
||||
|
||||
FCKPasteCommand.prototype =
|
||||
{
|
||||
Execute : function()
|
||||
{
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
FCK.Paste() ;
|
||||
else
|
||||
FCK.ExecuteNamedCommand( 'Paste' ) ;
|
||||
},
|
||||
|
||||
GetState : function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return FCK.GetNamedCommandState( 'Paste' ) ;
|
||||
}
|
||||
} ;
|
||||
|
||||
// FCKRuleCommand
|
||||
var FCKRuleCommand = function()
|
||||
{
|
||||
this.Name = 'Rule' ;
|
||||
}
|
||||
|
||||
FCKRuleCommand.prototype =
|
||||
{
|
||||
Execute : function()
|
||||
{
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
FCK.InsertElement( 'hr' ) ;
|
||||
},
|
||||
|
||||
GetState : function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return FCK.GetNamedCommandState( 'InsertHorizontalRule' ) ;
|
||||
}
|
||||
} ;
|
||||
|
||||
// FCKCutCopyCommand
|
||||
var FCKCutCopyCommand = function( isCut )
|
||||
{
|
||||
this.Name = isCut ? 'Cut' : 'Copy' ;
|
||||
}
|
||||
|
||||
FCKCutCopyCommand.prototype =
|
||||
{
|
||||
Execute : function()
|
||||
{
|
||||
var enabled = false ;
|
||||
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
{
|
||||
// The following seems to be the only reliable way to detect that
|
||||
// cut/copy is enabled in IE. It will fire the oncut/oncopy event
|
||||
// only if the security settings enabled the command to execute.
|
||||
|
||||
var onEvent = function()
|
||||
{
|
||||
enabled = true ;
|
||||
} ;
|
||||
|
||||
var eventName = 'on' + this.Name.toLowerCase() ;
|
||||
|
||||
FCK.EditorDocument.body.attachEvent( eventName, onEvent ) ;
|
||||
FCK.ExecuteNamedCommand( this.Name ) ;
|
||||
FCK.EditorDocument.body.detachEvent( eventName, onEvent ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// Other browsers throw an error if the command is disabled.
|
||||
FCK.ExecuteNamedCommand( this.Name ) ;
|
||||
enabled = true ;
|
||||
}
|
||||
catch(e){}
|
||||
}
|
||||
|
||||
if ( !enabled )
|
||||
alert( FCKLang[ 'PasteError' + this.Name ] ) ;
|
||||
},
|
||||
|
||||
GetState : function()
|
||||
{
|
||||
// Strangely, the Cut command happens to have the correct states for
|
||||
// both Copy and Cut in all browsers.
|
||||
return FCK.EditMode != FCK_EDITMODE_WYSIWYG ?
|
||||
FCK_TRISTATE_DISABLED :
|
||||
FCK.GetNamedCommandState( 'Cut' ) ;
|
||||
}
|
||||
};
|
||||
|
||||
var FCKAnchorDeleteCommand = function()
|
||||
{
|
||||
this.Name = 'AnchorDelete' ;
|
||||
}
|
||||
|
||||
FCKAnchorDeleteCommand.prototype =
|
||||
{
|
||||
Execute : function()
|
||||
{
|
||||
if (FCK.Selection.GetType() == 'Control')
|
||||
{
|
||||
FCK.Selection.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
var oFakeImage = FCK.Selection.GetSelectedElement() ;
|
||||
if ( oFakeImage )
|
||||
{
|
||||
if ( oFakeImage.tagName == 'IMG' && oFakeImage.getAttribute('_fckanchor') )
|
||||
oAnchor = FCK.GetRealElement( oFakeImage ) ;
|
||||
else
|
||||
oFakeImage = null ;
|
||||
}
|
||||
|
||||
//Search for a real anchor
|
||||
if ( !oFakeImage )
|
||||
{
|
||||
oAnchor = FCK.Selection.MoveToAncestorNode( 'A' ) ;
|
||||
if ( oAnchor )
|
||||
FCK.Selection.SelectNode( oAnchor ) ;
|
||||
}
|
||||
|
||||
// If it's also a link, then just remove the name and exit
|
||||
if ( oAnchor.href.length != 0 )
|
||||
{
|
||||
oAnchor.removeAttribute( 'name' ) ;
|
||||
// Remove temporary class for IE
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
oAnchor.className = oAnchor.className.replace( FCKRegexLib.FCK_Class, '' ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
// We need to remove the anchor
|
||||
// If we got a fake image, then just remove it and we're done
|
||||
if ( oFakeImage )
|
||||
{
|
||||
oFakeImage.parentNode.removeChild( oFakeImage ) ;
|
||||
return ;
|
||||
}
|
||||
// Empty anchor, so just remove it
|
||||
if ( oAnchor.innerHTML.length == 0 )
|
||||
{
|
||||
oAnchor.parentNode.removeChild( oAnchor ) ;
|
||||
return ;
|
||||
}
|
||||
// Anchor with content, leave the content
|
||||
FCKTools.RemoveOuterTags( oAnchor ) ;
|
||||
}
|
||||
if ( FCKBrowserInfo.IsGecko )
|
||||
FCK.Selection.Collapse( true ) ;
|
||||
},
|
||||
|
||||
GetState : function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return FCK.GetNamedCommandState( 'Unlink') ;
|
||||
}
|
||||
};
|
||||
|
||||
var FCKDeleteDivCommand = function()
|
||||
{
|
||||
}
|
||||
FCKDeleteDivCommand.prototype =
|
||||
{
|
||||
GetState : function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
|
||||
var node = FCKSelection.GetParentElement() ;
|
||||
var path = new FCKElementPath( node ) ;
|
||||
return path.BlockLimit && path.BlockLimit.nodeName.IEquals( 'div' ) ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
|
||||
},
|
||||
|
||||
Execute : function()
|
||||
{
|
||||
// Create an undo snapshot before doing anything.
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
// Find out the nodes to delete.
|
||||
var nodes = FCKDomTools.GetSelectedDivContainers() ;
|
||||
|
||||
// Remember the current selection position.
|
||||
var range = new FCKDomRange( FCK.EditorWindow ) ;
|
||||
range.MoveToSelection() ;
|
||||
var bookmark = range.CreateBookmark() ;
|
||||
|
||||
// Delete the container DIV node.
|
||||
for ( var i = 0 ; i < nodes.length ; i++)
|
||||
FCKDomTools.RemoveNode( nodes[i], true ) ;
|
||||
|
||||
// Restore selection.
|
||||
range.MoveToBookmark( bookmark ) ;
|
||||
range.Select() ;
|
||||
}
|
||||
} ;
|
||||
|
||||
// FCKRuleCommand
|
||||
var FCKNbsp = function()
|
||||
{
|
||||
this.Name = 'Non Breaking Space' ;
|
||||
}
|
||||
|
||||
FCKNbsp.prototype =
|
||||
{
|
||||
Execute : function()
|
||||
{
|
||||
FCK.InsertHtml( ' ' ) ;
|
||||
},
|
||||
|
||||
GetState : function()
|
||||
{
|
||||
return ( FCK.EditMode != FCK_EDITMODE_WYSIWYG ? FCK_TRISTATE_DISABLED : FCK_TRISTATE_OFF ) ;
|
||||
}
|
||||
} ;
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKBlockQuoteCommand Class: adds or removes blockquote tags.
|
||||
*/
|
||||
|
||||
var FCKBlockQuoteCommand = function()
|
||||
{
|
||||
}
|
||||
|
||||
FCKBlockQuoteCommand.prototype =
|
||||
{
|
||||
Execute : function()
|
||||
{
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
var state = this.GetState() ;
|
||||
|
||||
var range = new FCKDomRange( FCK.EditorWindow ) ;
|
||||
range.MoveToSelection() ;
|
||||
|
||||
var bookmark = range.CreateBookmark() ;
|
||||
|
||||
// Kludge for #1592: if the bookmark nodes are in the beginning of
|
||||
// blockquote, then move them to the nearest block element in the
|
||||
// blockquote.
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
{
|
||||
var bStart = range.GetBookmarkNode( bookmark, true ) ;
|
||||
var bEnd = range.GetBookmarkNode( bookmark, false ) ;
|
||||
|
||||
var cursor ;
|
||||
|
||||
if ( bStart
|
||||
&& bStart.parentNode.nodeName.IEquals( 'blockquote' )
|
||||
&& !bStart.previousSibling )
|
||||
{
|
||||
cursor = bStart ;
|
||||
while ( ( cursor = cursor.nextSibling ) )
|
||||
{
|
||||
if ( FCKListsLib.BlockElements[ cursor.nodeName.toLowerCase() ] )
|
||||
FCKDomTools.MoveNode( bStart, cursor, true ) ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bEnd
|
||||
&& bEnd.parentNode.nodeName.IEquals( 'blockquote' )
|
||||
&& !bEnd.previousSibling )
|
||||
{
|
||||
cursor = bEnd ;
|
||||
while ( ( cursor = cursor.nextSibling ) )
|
||||
{
|
||||
if ( FCKListsLib.BlockElements[ cursor.nodeName.toLowerCase() ] )
|
||||
{
|
||||
if ( cursor.firstChild == bStart )
|
||||
FCKDomTools.InsertAfterNode( bStart, bEnd ) ;
|
||||
else
|
||||
FCKDomTools.MoveNode( bEnd, cursor, true ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var iterator = new FCKDomRangeIterator( range ) ;
|
||||
var block ;
|
||||
|
||||
if ( state == FCK_TRISTATE_OFF )
|
||||
{
|
||||
iterator.EnforceRealBlocks = true ;
|
||||
var paragraphs = [] ;
|
||||
while ( ( block = iterator.GetNextParagraph() ) )
|
||||
paragraphs.push( block ) ;
|
||||
|
||||
// If no paragraphs, create one from the current selection position.
|
||||
if ( paragraphs.length < 1 )
|
||||
{
|
||||
para = range.Window.document.createElement( FCKConfig.EnterMode.IEquals( 'p' ) ? 'p' : 'div' ) ;
|
||||
range.InsertNode( para ) ;
|
||||
para.appendChild( range.Window.document.createTextNode( '\ufeff' ) ) ;
|
||||
range.MoveToBookmark( bookmark ) ;
|
||||
range.MoveToNodeContents( para ) ;
|
||||
range.Collapse( true ) ;
|
||||
bookmark = range.CreateBookmark() ;
|
||||
paragraphs.push( para ) ;
|
||||
}
|
||||
|
||||
// Make sure all paragraphs have the same parent.
|
||||
var commonParent = paragraphs[0].parentNode ;
|
||||
var tmp = [] ;
|
||||
for ( var i = 0 ; i < paragraphs.length ; i++ )
|
||||
{
|
||||
block = paragraphs[i] ;
|
||||
commonParent = FCKDomTools.GetCommonParents( block.parentNode, commonParent ).pop() ;
|
||||
}
|
||||
var lastBlock = null ;
|
||||
while ( paragraphs.length > 0 )
|
||||
{
|
||||
block = paragraphs.shift() ;
|
||||
while ( block.parentNode != commonParent )
|
||||
block = block.parentNode ;
|
||||
if ( block != lastBlock )
|
||||
tmp.push( block ) ;
|
||||
lastBlock = block ;
|
||||
}
|
||||
|
||||
// If any of the selected blocks is a blockquote, remove it to prevent nested blockquotes.
|
||||
while ( tmp.length > 0 )
|
||||
{
|
||||
block = tmp.shift() ;
|
||||
if ( block.nodeName.IEquals( 'blockquote' ) )
|
||||
{
|
||||
var docFrag = FCKTools.GetElementDocument( block ).createDocumentFragment() ;
|
||||
while ( block.firstChild )
|
||||
{
|
||||
docFrag.appendChild( block.removeChild( block.firstChild ) ) ;
|
||||
paragraphs.push( docFrag.lastChild ) ;
|
||||
}
|
||||
block.parentNode.replaceChild( docFrag, block ) ;
|
||||
}
|
||||
else
|
||||
paragraphs.push( block ) ;
|
||||
}
|
||||
|
||||
// Now we have all the blocks to be included in a new blockquote node.
|
||||
var bqBlock = range.Window.document.createElement( 'blockquote' ) ;
|
||||
commonParent.insertBefore( bqBlock, paragraphs[0] ) ;
|
||||
while ( paragraphs.length > 0 )
|
||||
{
|
||||
block = paragraphs.shift() ;
|
||||
bqBlock.appendChild( block ) ;
|
||||
}
|
||||
}
|
||||
else if ( state == FCK_TRISTATE_ON )
|
||||
{
|
||||
var moveOutNodes = [] ;
|
||||
while ( ( block = iterator.GetNextParagraph() ) )
|
||||
{
|
||||
var bqParent = null ;
|
||||
var bqChild = null ;
|
||||
while ( block.parentNode )
|
||||
{
|
||||
if ( block.parentNode.nodeName.IEquals( 'blockquote' ) )
|
||||
{
|
||||
bqParent = block.parentNode ;
|
||||
bqChild = block ;
|
||||
break ;
|
||||
}
|
||||
block = block.parentNode ;
|
||||
}
|
||||
|
||||
if ( bqParent && bqChild )
|
||||
moveOutNodes.push( bqChild ) ;
|
||||
}
|
||||
|
||||
var movedNodes = [] ;
|
||||
while ( moveOutNodes.length > 0 )
|
||||
{
|
||||
var node = moveOutNodes.shift() ;
|
||||
var bqBlock = node.parentNode ;
|
||||
|
||||
// If the node is located at the beginning or the end, just take it out without splitting.
|
||||
// Otherwise, split the blockquote node and move the paragraph in between the two blockquote nodes.
|
||||
if ( node == node.parentNode.firstChild )
|
||||
{
|
||||
bqBlock.parentNode.insertBefore( bqBlock.removeChild( node ), bqBlock ) ;
|
||||
if ( ! bqBlock.firstChild )
|
||||
bqBlock.parentNode.removeChild( bqBlock ) ;
|
||||
}
|
||||
else if ( node == node.parentNode.lastChild )
|
||||
{
|
||||
bqBlock.parentNode.insertBefore( bqBlock.removeChild( node ), bqBlock.nextSibling ) ;
|
||||
if ( ! bqBlock.firstChild )
|
||||
bqBlock.parentNode.removeChild( bqBlock ) ;
|
||||
}
|
||||
else
|
||||
FCKDomTools.BreakParent( node, node.parentNode, range ) ;
|
||||
|
||||
movedNodes.push( node ) ;
|
||||
}
|
||||
|
||||
if ( FCKConfig.EnterMode.IEquals( 'br' ) )
|
||||
{
|
||||
while ( movedNodes.length )
|
||||
{
|
||||
var node = movedNodes.shift() ;
|
||||
var firstTime = true ;
|
||||
if ( node.nodeName.IEquals( 'div' ) )
|
||||
{
|
||||
var docFrag = FCKTools.GetElementDocument( node ).createDocumentFragment() ;
|
||||
var needBeginBr = firstTime && node.previousSibling &&
|
||||
!FCKListsLib.BlockBoundaries[node.previousSibling.nodeName.toLowerCase()] ;
|
||||
if ( firstTime && needBeginBr )
|
||||
docFrag.appendChild( FCKTools.GetElementDocument( node ).createElement( 'br' ) ) ;
|
||||
var needEndBr = node.nextSibling &&
|
||||
!FCKListsLib.BlockBoundaries[node.nextSibling.nodeName.toLowerCase()] ;
|
||||
while ( node.firstChild )
|
||||
docFrag.appendChild( node.removeChild( node.firstChild ) ) ;
|
||||
if ( needEndBr )
|
||||
docFrag.appendChild( FCKTools.GetElementDocument( node ).createElement( 'br' ) ) ;
|
||||
node.parentNode.replaceChild( docFrag, node ) ;
|
||||
firstTime = false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
range.MoveToBookmark( bookmark ) ;
|
||||
range.Select() ;
|
||||
|
||||
FCK.Focus() ;
|
||||
FCK.Events.FireEvent( 'OnSelectionChange' ) ;
|
||||
},
|
||||
|
||||
GetState : function()
|
||||
{
|
||||
// Disabled if not WYSIWYG.
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || ! FCK.EditorWindow )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
|
||||
var path = new FCKElementPath( FCKSelection.GetBoundaryParentElement( true ) ) ;
|
||||
var firstBlock = path.Block || path.BlockLimit ;
|
||||
|
||||
if ( !firstBlock || firstBlock.nodeName.toLowerCase() == 'body' )
|
||||
return FCK_TRISTATE_OFF ;
|
||||
|
||||
// See if the first block has a blockquote parent.
|
||||
for ( var i = 0 ; i < path.Elements.length ; i++ )
|
||||
{
|
||||
if ( path.Elements[i].nodeName.IEquals( 'blockquote' ) )
|
||||
return FCK_TRISTATE_ON ;
|
||||
}
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
} ;
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKCoreStyleCommand Class: controls the execution of a core style. Core
|
||||
* styles are usually represented as buttons in the toolbar., like Bold and
|
||||
* Italic.
|
||||
*/
|
||||
|
||||
var FCKCoreStyleCommand = function( coreStyleName )
|
||||
{
|
||||
this.Name = 'CoreStyle' ;
|
||||
this.StyleName = '_FCK_' + coreStyleName ;
|
||||
this.IsActive = false ;
|
||||
|
||||
FCKStyles.AttachStyleStateChange( this.StyleName, this._OnStyleStateChange, this ) ;
|
||||
}
|
||||
|
||||
FCKCoreStyleCommand.prototype =
|
||||
{
|
||||
Execute : function()
|
||||
{
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
if ( this.IsActive )
|
||||
FCKStyles.RemoveStyle( this.StyleName ) ;
|
||||
else
|
||||
FCKStyles.ApplyStyle( this.StyleName ) ;
|
||||
|
||||
FCK.Focus() ;
|
||||
FCK.Events.FireEvent( 'OnSelectionChange' ) ;
|
||||
},
|
||||
|
||||
GetState : function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return this.IsActive ? FCK_TRISTATE_ON : FCK_TRISTATE_OFF ;
|
||||
},
|
||||
|
||||
_OnStyleStateChange : function( styleName, isActive )
|
||||
{
|
||||
this.IsActive = isActive ;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Stretch the editor to full window size and back.
|
||||
*/
|
||||
|
||||
var FCKFitWindow = function()
|
||||
{
|
||||
this.Name = 'FitWindow' ;
|
||||
}
|
||||
|
||||
FCKFitWindow.prototype.Execute = function()
|
||||
{
|
||||
var eEditorFrame = window.frameElement ;
|
||||
var eEditorFrameStyle = eEditorFrame.style ;
|
||||
|
||||
var eMainWindow = parent ;
|
||||
var eDocEl = eMainWindow.document.documentElement ;
|
||||
var eBody = eMainWindow.document.body ;
|
||||
var eBodyStyle = eBody.style ;
|
||||
var eParent ;
|
||||
|
||||
// Save the current selection and scroll position.
|
||||
var oRange = new FCKDomRange( FCK.EditorWindow ) ;
|
||||
oRange.MoveToSelection() ;
|
||||
var oEditorScrollPos = FCKTools.GetScrollPosition( FCK.EditorWindow ) ;
|
||||
|
||||
// No original style properties known? Go fullscreen.
|
||||
if ( !this.IsMaximized )
|
||||
{
|
||||
// Registering an event handler when the window gets resized.
|
||||
if( FCKBrowserInfo.IsIE )
|
||||
eMainWindow.attachEvent( 'onresize', FCKFitWindow_Resize ) ;
|
||||
else
|
||||
eMainWindow.addEventListener( 'resize', FCKFitWindow_Resize, true ) ;
|
||||
|
||||
// Save the scrollbars position.
|
||||
this._ScrollPos = FCKTools.GetScrollPosition( eMainWindow ) ;
|
||||
|
||||
// Save and reset the styles for the entire node tree. They could interfere in the result.
|
||||
eParent = eEditorFrame ;
|
||||
// The extra () is to avoid a warning with strict error checking. This is ok.
|
||||
while( (eParent = eParent.parentNode) )
|
||||
{
|
||||
if ( eParent.nodeType == 1 )
|
||||
{
|
||||
eParent._fckSavedStyles = FCKTools.SaveStyles( eParent ) ;
|
||||
eParent.style.zIndex = FCKConfig.FloatingPanelsZIndex - 1 ;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide IE scrollbars (in strict mode).
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
{
|
||||
this.documentElementOverflow = eDocEl.style.overflow ;
|
||||
eDocEl.style.overflow = 'hidden' ;
|
||||
eBodyStyle.overflow = 'hidden' ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hide the scroolbars in Firefox.
|
||||
eBodyStyle.overflow = 'hidden' ;
|
||||
eBodyStyle.width = '0px' ;
|
||||
eBodyStyle.height = '0px' ;
|
||||
}
|
||||
|
||||
// Save the IFRAME styles.
|
||||
this._EditorFrameStyles = FCKTools.SaveStyles( eEditorFrame ) ;
|
||||
|
||||
// Resize.
|
||||
var oViewPaneSize = FCKTools.GetViewPaneSize( eMainWindow ) ;
|
||||
|
||||
eEditorFrameStyle.position = "absolute";
|
||||
eEditorFrame.offsetLeft ; // Kludge for Safari 3.1 browser bug, do not remove. See #2066.
|
||||
eEditorFrameStyle.zIndex = FCKConfig.FloatingPanelsZIndex - 1;
|
||||
eEditorFrameStyle.left = "0px";
|
||||
eEditorFrameStyle.top = "0px";
|
||||
eEditorFrameStyle.width = oViewPaneSize.Width + "px";
|
||||
eEditorFrameStyle.height = oViewPaneSize.Height + "px";
|
||||
|
||||
// Giving the frame some (huge) borders on his right and bottom
|
||||
// side to hide the background that would otherwise show when the
|
||||
// editor is in fullsize mode and the window is increased in size
|
||||
// not for IE, because IE immediately adapts the editor on resize,
|
||||
// without showing any of the background oddly in firefox, the
|
||||
// editor seems not to fill the whole frame, so just setting the
|
||||
// background of it to white to cover the page laying behind it anyway.
|
||||
if ( !FCKBrowserInfo.IsIE )
|
||||
{
|
||||
eEditorFrameStyle.borderRight = eEditorFrameStyle.borderBottom = "9999px solid white" ;
|
||||
eEditorFrameStyle.backgroundColor = "white";
|
||||
}
|
||||
|
||||
// Scroll to top left.
|
||||
eMainWindow.scrollTo(0, 0);
|
||||
|
||||
// Is the editor still not on the top left? Let's find out and fix that as well. (Bug #174)
|
||||
var editorPos = FCKTools.GetWindowPosition( eMainWindow, eEditorFrame ) ;
|
||||
if ( editorPos.x != 0 )
|
||||
eEditorFrameStyle.left = ( -1 * editorPos.x ) + "px" ;
|
||||
if ( editorPos.y != 0 )
|
||||
eEditorFrameStyle.top = ( -1 * editorPos.y ) + "px" ;
|
||||
|
||||
this.IsMaximized = true ;
|
||||
}
|
||||
else // Resize to original size.
|
||||
{
|
||||
// Remove the event handler of window resizing.
|
||||
if( FCKBrowserInfo.IsIE )
|
||||
eMainWindow.detachEvent( "onresize", FCKFitWindow_Resize ) ;
|
||||
else
|
||||
eMainWindow.removeEventListener( "resize", FCKFitWindow_Resize, true ) ;
|
||||
|
||||
// Restore the CSS position for the entire node tree.
|
||||
eParent = eEditorFrame ;
|
||||
// The extra () is to avoid a warning with strict error checking. This is ok.
|
||||
while( (eParent = eParent.parentNode) )
|
||||
{
|
||||
if ( eParent._fckSavedStyles )
|
||||
{
|
||||
FCKTools.RestoreStyles( eParent, eParent._fckSavedStyles ) ;
|
||||
eParent._fckSavedStyles = null ;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore IE scrollbars
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
eDocEl.style.overflow = this.documentElementOverflow ;
|
||||
|
||||
// Restore original size
|
||||
FCKTools.RestoreStyles( eEditorFrame, this._EditorFrameStyles ) ;
|
||||
|
||||
// Restore the window scroll position.
|
||||
eMainWindow.scrollTo( this._ScrollPos.X, this._ScrollPos.Y ) ;
|
||||
|
||||
this.IsMaximized = false ;
|
||||
}
|
||||
|
||||
FCKToolbarItems.GetItem('FitWindow').RefreshState() ;
|
||||
|
||||
// It seams that Firefox restarts the editing area when making this changes.
|
||||
// On FF 1.0.x, the area is not anymore editable. On FF 1.5+, the special
|
||||
//configuration, like DisableFFTableHandles and DisableObjectResizing get
|
||||
//lost, so we must reset it. Also, the cursor position and selection are
|
||||
//also lost, even if you comment the following line (MakeEditable).
|
||||
// if ( FCKBrowserInfo.IsGecko10 ) // Initially I thought it was a FF 1.0 only problem.
|
||||
if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )
|
||||
FCK.EditingArea.MakeEditable() ;
|
||||
|
||||
FCK.Focus() ;
|
||||
|
||||
// Restore the selection and scroll position of inside the document.
|
||||
oRange.Select() ;
|
||||
FCK.EditorWindow.scrollTo( oEditorScrollPos.X, oEditorScrollPos.Y ) ;
|
||||
}
|
||||
|
||||
FCKFitWindow.prototype.GetState = function()
|
||||
{
|
||||
if ( FCKConfig.ToolbarLocation != 'In' )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
else
|
||||
return ( this.IsMaximized ? FCK_TRISTATE_ON : FCK_TRISTATE_OFF );
|
||||
}
|
||||
|
||||
function FCKFitWindow_Resize()
|
||||
{
|
||||
var oViewPaneSize = FCKTools.GetViewPaneSize( parent ) ;
|
||||
|
||||
var eEditorFrameStyle = window.frameElement.style ;
|
||||
|
||||
eEditorFrameStyle.width = oViewPaneSize.Width + 'px' ;
|
||||
eEditorFrameStyle.height = oViewPaneSize.Height + 'px' ;
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKIndentCommand Class: controls block indentation.
|
||||
*/
|
||||
|
||||
var FCKIndentCommand = function( name, offset )
|
||||
{
|
||||
this.Name = name ;
|
||||
this.Offset = offset ;
|
||||
this.IndentCSSProperty = FCKConfig.ContentLangDirection.IEquals( 'ltr' ) ? 'marginLeft' : 'marginRight' ;
|
||||
}
|
||||
|
||||
FCKIndentCommand._InitIndentModeParameters = function()
|
||||
{
|
||||
if ( FCKConfig.IndentClasses && FCKConfig.IndentClasses.length > 0 )
|
||||
{
|
||||
this._UseIndentClasses = true ;
|
||||
this._IndentClassMap = {} ;
|
||||
for ( var i = 0 ; i < FCKConfig.IndentClasses.length ;i++ )
|
||||
this._IndentClassMap[FCKConfig.IndentClasses[i]] = i + 1 ;
|
||||
this._ClassNameRegex = new RegExp( '(?:^|\\s+)(' + FCKConfig.IndentClasses.join( '|' ) + ')(?=$|\\s)' ) ;
|
||||
}
|
||||
else
|
||||
this._UseIndentClasses = false ;
|
||||
}
|
||||
|
||||
|
||||
FCKIndentCommand.prototype =
|
||||
{
|
||||
Execute : function()
|
||||
{
|
||||
// Save an undo snapshot before doing anything.
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
var range = new FCKDomRange( FCK.EditorWindow ) ;
|
||||
range.MoveToSelection() ;
|
||||
var bookmark = range.CreateBookmark() ;
|
||||
|
||||
// Two cases to handle here: either we're in a list, or not.
|
||||
// If we're in a list, then the indent/outdent operations would be done on the list nodes.
|
||||
// Otherwise, apply the operation on the nearest block nodes.
|
||||
var nearestListBlock = FCKDomTools.GetCommonParentNode( range.StartNode || range.StartContainer ,
|
||||
range.EndNode || range.EndContainer,
|
||||
['ul', 'ol'] ) ;
|
||||
if ( nearestListBlock )
|
||||
this._IndentList( range, nearestListBlock ) ;
|
||||
else
|
||||
this._IndentBlock( range ) ;
|
||||
|
||||
range.MoveToBookmark( bookmark ) ;
|
||||
range.Select() ;
|
||||
|
||||
FCK.Focus() ;
|
||||
FCK.Events.FireEvent( 'OnSelectionChange' ) ;
|
||||
},
|
||||
|
||||
GetState : function()
|
||||
{
|
||||
// Disabled if not WYSIWYG.
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || ! FCK.EditorWindow )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
|
||||
// Initialize parameters if not already initialzed.
|
||||
if ( FCKIndentCommand._UseIndentClasses == undefined )
|
||||
FCKIndentCommand._InitIndentModeParameters() ;
|
||||
|
||||
// If we're not in a list, and the starting block's indentation is zero, and the current
|
||||
// command is the outdent command, then we should return FCK_TRISTATE_DISABLED.
|
||||
var startContainer = FCKSelection.GetBoundaryParentElement( true ) ;
|
||||
var endContainer = FCKSelection.GetBoundaryParentElement( false ) ;
|
||||
var listNode = FCKDomTools.GetCommonParentNode( startContainer, endContainer, ['ul','ol'] ) ;
|
||||
|
||||
if ( listNode )
|
||||
{
|
||||
if ( this.Name.IEquals( 'outdent' ) )
|
||||
return FCK_TRISTATE_OFF ;
|
||||
var firstItem = FCKTools.GetElementAscensor( startContainer, 'li' ) ;
|
||||
if ( !firstItem || !firstItem.previousSibling )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
if ( ! FCKIndentCommand._UseIndentClasses && this.Name.IEquals( 'indent' ) )
|
||||
return FCK_TRISTATE_OFF;
|
||||
|
||||
var path = new FCKElementPath( startContainer ) ;
|
||||
var firstBlock = path.Block || path.BlockLimit ;
|
||||
if ( !firstBlock )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
|
||||
if ( FCKIndentCommand._UseIndentClasses )
|
||||
{
|
||||
var indentClass = firstBlock.className.match( FCKIndentCommand._ClassNameRegex ) ;
|
||||
var indentStep = 0 ;
|
||||
if ( indentClass != null )
|
||||
{
|
||||
indentClass = indentClass[1] ;
|
||||
indentStep = FCKIndentCommand._IndentClassMap[indentClass] ;
|
||||
}
|
||||
if ( ( this.Name == 'outdent' && indentStep == 0 ) ||
|
||||
( this.Name == 'indent' && indentStep == FCKConfig.IndentClasses.length ) )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
else
|
||||
{
|
||||
var indent = parseInt( firstBlock.style[this.IndentCSSProperty], 10 ) ;
|
||||
if ( isNaN( indent ) )
|
||||
indent = 0 ;
|
||||
if ( indent <= 0 )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
},
|
||||
|
||||
_IndentBlock : function( range )
|
||||
{
|
||||
var iterator = new FCKDomRangeIterator( range ) ;
|
||||
iterator.EnforceRealBlocks = true ;
|
||||
|
||||
range.Expand( 'block_contents' ) ;
|
||||
var commonParents = FCKDomTools.GetCommonParents( range.StartContainer, range.EndContainer ) ;
|
||||
var nearestParent = commonParents[commonParents.length - 1] ;
|
||||
var block ;
|
||||
|
||||
while ( ( block = iterator.GetNextParagraph() ) )
|
||||
{
|
||||
// We don't want to indent subtrees recursively, so only perform the indent operation
|
||||
// if the block itself is the nearestParent, or the block's parent is the nearestParent.
|
||||
if ( ! ( block == nearestParent || block.parentNode == nearestParent ) )
|
||||
continue ;
|
||||
|
||||
if ( FCKIndentCommand._UseIndentClasses )
|
||||
{
|
||||
// Transform current class name to indent step index.
|
||||
var indentClass = block.className.match( FCKIndentCommand._ClassNameRegex ) ;
|
||||
var indentStep = 0 ;
|
||||
if ( indentClass != null )
|
||||
{
|
||||
indentClass = indentClass[1] ;
|
||||
indentStep = FCKIndentCommand._IndentClassMap[indentClass] ;
|
||||
}
|
||||
|
||||
// Operate on indent step index, transform indent step index back to class name.
|
||||
if ( this.Name.IEquals( 'outdent' ) )
|
||||
indentStep-- ;
|
||||
else if ( this.Name.IEquals( 'indent' ) )
|
||||
indentStep++ ;
|
||||
indentStep = Math.min( indentStep, FCKConfig.IndentClasses.length ) ;
|
||||
indentStep = Math.max( indentStep, 0 ) ;
|
||||
var className = block.className.replace( FCKIndentCommand._ClassNameRegex, '' ) ;
|
||||
if ( indentStep < 1 )
|
||||
block.className = className ;
|
||||
else
|
||||
block.className = ( className.length > 0 ? className + ' ' : '' ) +
|
||||
FCKConfig.IndentClasses[indentStep - 1] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Offset distance is assumed to be in pixels for now.
|
||||
var currentOffset = parseInt( block.style[this.IndentCSSProperty], 10 ) ;
|
||||
if ( isNaN( currentOffset ) )
|
||||
currentOffset = 0 ;
|
||||
currentOffset += this.Offset ;
|
||||
currentOffset = Math.max( currentOffset, 0 ) ;
|
||||
currentOffset = Math.ceil( currentOffset / this.Offset ) * this.Offset ;
|
||||
block.style[this.IndentCSSProperty] = currentOffset ? currentOffset + FCKConfig.IndentUnit : '' ;
|
||||
if ( block.getAttribute( 'style' ) == '' )
|
||||
block.removeAttribute( 'style' ) ;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_IndentList : function( range, listNode )
|
||||
{
|
||||
// Our starting and ending points of the range might be inside some blocks under a list item...
|
||||
// So before playing with the iterator, we need to expand the block to include the list items.
|
||||
var startContainer = range.StartContainer ;
|
||||
var endContainer = range.EndContainer ;
|
||||
while ( startContainer && startContainer.parentNode != listNode )
|
||||
startContainer = startContainer.parentNode ;
|
||||
while ( endContainer && endContainer.parentNode != listNode )
|
||||
endContainer = endContainer.parentNode ;
|
||||
|
||||
if ( ! startContainer || ! endContainer )
|
||||
return ;
|
||||
|
||||
// Now we can iterate over the individual items on the same tree depth.
|
||||
var block = startContainer ;
|
||||
var itemsToMove = [] ;
|
||||
var stopFlag = false ;
|
||||
while ( stopFlag == false )
|
||||
{
|
||||
if ( block == endContainer )
|
||||
stopFlag = true ;
|
||||
itemsToMove.push( block ) ;
|
||||
block = block.nextSibling ;
|
||||
}
|
||||
if ( itemsToMove.length < 1 )
|
||||
return ;
|
||||
|
||||
// Do indent or outdent operations on the array model of the list, not the list's DOM tree itself.
|
||||
// The array model demands that it knows as much as possible about the surrounding lists, we need
|
||||
// to feed it the further ancestor node that is still a list.
|
||||
var listParents = FCKDomTools.GetParents( listNode ) ;
|
||||
for ( var i = 0 ; i < listParents.length ; i++ )
|
||||
{
|
||||
if ( listParents[i].nodeName.IEquals( ['ul', 'ol'] ) )
|
||||
{
|
||||
listNode = listParents[i] ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
var indentOffset = this.Name.IEquals( 'indent' ) ? 1 : -1 ;
|
||||
var startItem = itemsToMove[0] ;
|
||||
var lastItem = itemsToMove[ itemsToMove.length - 1 ] ;
|
||||
var markerObj = {} ;
|
||||
|
||||
// Convert the list DOM tree into a one dimensional array.
|
||||
var listArray = FCKDomTools.ListToArray( listNode, markerObj ) ;
|
||||
|
||||
// Apply indenting or outdenting on the array.
|
||||
var baseIndent = listArray[lastItem._FCK_ListArray_Index].indent ;
|
||||
for ( var i = startItem._FCK_ListArray_Index ; i <= lastItem._FCK_ListArray_Index ; i++ )
|
||||
listArray[i].indent += indentOffset ;
|
||||
for ( var i = lastItem._FCK_ListArray_Index + 1 ; i < listArray.length && listArray[i].indent > baseIndent ; i++ )
|
||||
listArray[i].indent += indentOffset ;
|
||||
|
||||
/* For debug use only
|
||||
var PrintArray = function( listArray, doc )
|
||||
{
|
||||
var s = [] ;
|
||||
for ( var i = 0 ; i < listArray.length ; i++ )
|
||||
{
|
||||
for ( var j in listArray[i] )
|
||||
{
|
||||
if ( j != 'contents' )
|
||||
s.push( j + ":" + listArray[i][j] + "; " ) ;
|
||||
else
|
||||
{
|
||||
var docFrag = doc.createDocumentFragment() ;
|
||||
var tmpNode = doc.createElement( 'span' ) ;
|
||||
for ( var k = 0 ; k < listArray[i][j].length ; k++ )
|
||||
docFrag.appendChild( listArray[i][j][k].cloneNode( true ) ) ;
|
||||
tmpNode.appendChild( docFrag ) ;
|
||||
s.push( j + ":" + tmpNode.innerHTML + "; ") ;
|
||||
}
|
||||
}
|
||||
s.push( '\n' ) ;
|
||||
}
|
||||
alert( s.join('') ) ;
|
||||
}
|
||||
PrintArray( listArray, FCK.EditorDocument ) ;
|
||||
*/
|
||||
|
||||
// Convert the array back to a DOM forest (yes we might have a few subtrees now).
|
||||
// And replace the old list with the new forest.
|
||||
var newList = FCKDomTools.ArrayToList( listArray ) ;
|
||||
if ( newList )
|
||||
listNode.parentNode.replaceChild( newList.listNode, listNode ) ;
|
||||
|
||||
// Clean up the markers.
|
||||
FCKDomTools.ClearAllMarkers( markerObj ) ;
|
||||
}
|
||||
} ;
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKJustifyCommand Class: controls block justification.
|
||||
*/
|
||||
|
||||
var FCKJustifyCommand = function( alignValue )
|
||||
{
|
||||
this.AlignValue = alignValue ;
|
||||
|
||||
// Detect whether this is the instance for the default alignment.
|
||||
var contentDir = FCKConfig.ContentLangDirection.toLowerCase() ;
|
||||
this.IsDefaultAlign = ( alignValue == 'left' && contentDir == 'ltr' ) ||
|
||||
( alignValue == 'right' && contentDir == 'rtl' ) ;
|
||||
|
||||
// Get the class name to be used by this instance.
|
||||
var cssClassName = this._CssClassName = ( function()
|
||||
{
|
||||
var classes = FCKConfig.JustifyClasses ;
|
||||
if ( classes )
|
||||
{
|
||||
switch ( alignValue )
|
||||
{
|
||||
case 'left' :
|
||||
return classes[0] || null ;
|
||||
case 'center' :
|
||||
return classes[1] || null ;
|
||||
case 'right' :
|
||||
return classes[2] || null ;
|
||||
case 'justify' :
|
||||
return classes[3] || null ;
|
||||
}
|
||||
}
|
||||
return null ;
|
||||
} )() ;
|
||||
|
||||
if ( cssClassName && cssClassName.length > 0 )
|
||||
this._CssClassRegex = new RegExp( '(?:^|\\s+)' + cssClassName + '(?=$|\\s)' ) ;
|
||||
}
|
||||
|
||||
FCKJustifyCommand._GetClassNameRegex = function()
|
||||
{
|
||||
var regex = FCKJustifyCommand._ClassRegex ;
|
||||
if ( regex != undefined )
|
||||
return regex ;
|
||||
|
||||
var names = [] ;
|
||||
|
||||
var classes = FCKConfig.JustifyClasses ;
|
||||
if ( classes )
|
||||
{
|
||||
for ( var i = 0 ; i < 4 ; i++ )
|
||||
{
|
||||
var className = classes[i] ;
|
||||
if ( className && className.length > 0 )
|
||||
names.push( className ) ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( names.length > 0 )
|
||||
regex = new RegExp( '(?:^|\\s+)(?:' + names.join( '|' ) + ')(?=$|\\s)' ) ;
|
||||
else
|
||||
regex = null ;
|
||||
|
||||
return FCKJustifyCommand._ClassRegex = regex ;
|
||||
}
|
||||
|
||||
FCKJustifyCommand.prototype =
|
||||
{
|
||||
Execute : function()
|
||||
{
|
||||
// Save an undo snapshot before doing anything.
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
var range = new FCKDomRange( FCK.EditorWindow ) ;
|
||||
range.MoveToSelection() ;
|
||||
|
||||
var currentState = this.GetState() ;
|
||||
if ( currentState == FCK_TRISTATE_DISABLED )
|
||||
return ;
|
||||
|
||||
// Store a bookmark of the selection since the paragraph iterator might
|
||||
// change the DOM tree and break selections.
|
||||
var bookmark = range.CreateBookmark() ;
|
||||
|
||||
var cssClassName = this._CssClassName ;
|
||||
|
||||
// Apply alignment setting for each paragraph.
|
||||
var iterator = new FCKDomRangeIterator( range ) ;
|
||||
var block ;
|
||||
while ( ( block = iterator.GetNextParagraph() ) )
|
||||
{
|
||||
block.removeAttribute( 'align' ) ;
|
||||
|
||||
if ( cssClassName )
|
||||
{
|
||||
// Remove the any of the alignment classes from the className.
|
||||
var className = block.className.replace( FCKJustifyCommand._GetClassNameRegex(), '' ) ;
|
||||
|
||||
// Append the desired class name.
|
||||
if ( currentState == FCK_TRISTATE_OFF )
|
||||
{
|
||||
if ( className.length > 0 )
|
||||
className += ' ' ;
|
||||
block.className = className + cssClassName ;
|
||||
}
|
||||
else if ( className.length == 0 )
|
||||
FCKDomTools.RemoveAttribute( block, 'class' ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
var style = block.style ;
|
||||
if ( currentState == FCK_TRISTATE_OFF )
|
||||
style.textAlign = this.AlignValue ;
|
||||
else
|
||||
{
|
||||
style.textAlign = '' ;
|
||||
if ( style.cssText.length == 0 )
|
||||
block.removeAttribute( 'style' ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restore previous selection.
|
||||
range.MoveToBookmark( bookmark ) ;
|
||||
range.Select() ;
|
||||
|
||||
FCK.Focus() ;
|
||||
FCK.Events.FireEvent( 'OnSelectionChange' ) ;
|
||||
},
|
||||
|
||||
GetState : function()
|
||||
{
|
||||
// Disabled if not WYSIWYG.
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || ! FCK.EditorWindow )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
|
||||
// Retrieve the first selected block.
|
||||
var path = new FCKElementPath( FCKSelection.GetBoundaryParentElement( true ) ) ;
|
||||
var firstBlock = path.Block || path.BlockLimit ;
|
||||
|
||||
if ( !firstBlock || firstBlock.nodeName.toLowerCase() == 'body' )
|
||||
return FCK_TRISTATE_OFF ;
|
||||
|
||||
// Check if the desired style is already applied to the block.
|
||||
var currentAlign ;
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
currentAlign = firstBlock.currentStyle.textAlign ;
|
||||
else
|
||||
currentAlign = FCK.EditorWindow.getComputedStyle( firstBlock, '' ).getPropertyValue( 'text-align' );
|
||||
currentAlign = currentAlign.replace( /(-moz-|-webkit-|start|auto)/i, '' );
|
||||
if ( ( !currentAlign && this.IsDefaultAlign ) || currentAlign == this.AlignValue )
|
||||
return FCK_TRISTATE_ON ;
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
} ;
|
||||
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Implementation for the "Insert/Remove Ordered/Unordered List" commands.
|
||||
*/
|
||||
|
||||
var FCKListCommand = function( name, tagName )
|
||||
{
|
||||
this.Name = name ;
|
||||
this.TagName = tagName ;
|
||||
}
|
||||
|
||||
FCKListCommand.prototype =
|
||||
{
|
||||
GetState : function()
|
||||
{
|
||||
// Disabled if not WYSIWYG.
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || ! FCK.EditorWindow )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
|
||||
// We'll use the style system's convention to determine list state here...
|
||||
// If the starting block is a descendant of an <ol> or <ul> node, then we're in a list.
|
||||
var startContainer = FCKSelection.GetBoundaryParentElement( true ) ;
|
||||
var listNode = startContainer ;
|
||||
while ( listNode )
|
||||
{
|
||||
if ( listNode.nodeName.IEquals( [ 'ul', 'ol' ] ) )
|
||||
break ;
|
||||
listNode = listNode.parentNode ;
|
||||
}
|
||||
if ( listNode && listNode.nodeName.IEquals( this.TagName ) )
|
||||
return FCK_TRISTATE_ON ;
|
||||
else
|
||||
return FCK_TRISTATE_OFF ;
|
||||
},
|
||||
|
||||
Execute : function()
|
||||
{
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
var doc = FCK.EditorDocument ;
|
||||
var range = new FCKDomRange( FCK.EditorWindow ) ;
|
||||
range.MoveToSelection() ;
|
||||
var state = this.GetState() ;
|
||||
|
||||
// Midas lists rule #1 says we can create a list even in an empty document.
|
||||
// But FCKDomRangeIterator wouldn't run if the document is really empty.
|
||||
// So create a paragraph if the document is empty and we're going to create a list.
|
||||
if ( state == FCK_TRISTATE_OFF )
|
||||
{
|
||||
FCKDomTools.TrimNode( doc.body ) ;
|
||||
if ( ! doc.body.firstChild )
|
||||
{
|
||||
var paragraph = doc.createElement( 'p' ) ;
|
||||
doc.body.appendChild( paragraph ) ;
|
||||
range.MoveToNodeContents( paragraph ) ;
|
||||
}
|
||||
}
|
||||
|
||||
var bookmark = range.CreateBookmark() ;
|
||||
|
||||
// Group the blocks up because there are many cases where multiple lists have to be created,
|
||||
// or multiple lists have to be cancelled.
|
||||
var listGroups = [] ;
|
||||
var markerObj = {} ;
|
||||
var iterator = new FCKDomRangeIterator( range ) ;
|
||||
var block ;
|
||||
|
||||
iterator.ForceBrBreak = ( state == FCK_TRISTATE_OFF ) ;
|
||||
var nextRangeExists = true ;
|
||||
var rangeQueue = null ;
|
||||
while ( nextRangeExists )
|
||||
{
|
||||
while ( ( block = iterator.GetNextParagraph() ) )
|
||||
{
|
||||
var path = new FCKElementPath( block ) ;
|
||||
var listNode = null ;
|
||||
var processedFlag = false ;
|
||||
var blockLimit = path.BlockLimit ;
|
||||
|
||||
// First, try to group by a list ancestor.
|
||||
for ( var i = path.Elements.length - 1 ; i >= 0 ; i-- )
|
||||
{
|
||||
var el = path.Elements[i] ;
|
||||
if ( el.nodeName.IEquals( ['ol', 'ul'] ) )
|
||||
{
|
||||
// If we've encountered a list inside a block limit
|
||||
// The last group object of the block limit element should
|
||||
// no longer be valid. Since paragraphs after the list
|
||||
// should belong to a different group of paragraphs before
|
||||
// the list. (Bug #1309)
|
||||
if ( blockLimit._FCK_ListGroupObject )
|
||||
blockLimit._FCK_ListGroupObject = null ;
|
||||
|
||||
var groupObj = el._FCK_ListGroupObject ;
|
||||
if ( groupObj )
|
||||
groupObj.contents.push( block ) ;
|
||||
else
|
||||
{
|
||||
groupObj = { 'root' : el, 'contents' : [ block ] } ;
|
||||
listGroups.push( groupObj ) ;
|
||||
FCKDomTools.SetElementMarker( markerObj, el, '_FCK_ListGroupObject', groupObj ) ;
|
||||
}
|
||||
processedFlag = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( processedFlag )
|
||||
continue ;
|
||||
|
||||
// No list ancestor? Group by block limit.
|
||||
var root = blockLimit ;
|
||||
if ( root._FCK_ListGroupObject )
|
||||
root._FCK_ListGroupObject.contents.push( block ) ;
|
||||
else
|
||||
{
|
||||
var groupObj = { 'root' : root, 'contents' : [ block ] } ;
|
||||
FCKDomTools.SetElementMarker( markerObj, root, '_FCK_ListGroupObject', groupObj ) ;
|
||||
listGroups.push( groupObj ) ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
nextRangeExists = false ;
|
||||
else
|
||||
{
|
||||
if ( rangeQueue == null )
|
||||
{
|
||||
rangeQueue = [] ;
|
||||
var selectionObject = FCKSelection.GetSelection() ;
|
||||
if ( selectionObject && listGroups.length == 0 )
|
||||
rangeQueue.push( selectionObject.getRangeAt( 0 ) ) ;
|
||||
for ( var i = 1 ; selectionObject && i < selectionObject.rangeCount ; i++ )
|
||||
rangeQueue.push( selectionObject.getRangeAt( i ) ) ;
|
||||
}
|
||||
if ( rangeQueue.length < 1 )
|
||||
nextRangeExists = false ;
|
||||
else
|
||||
{
|
||||
var internalRange = FCKW3CRange.CreateFromRange( doc, rangeQueue.shift() ) ;
|
||||
range._Range = internalRange ;
|
||||
range._UpdateElementInfo() ;
|
||||
if ( range.StartNode.nodeName.IEquals( 'td' ) )
|
||||
range.SetStart( range.StartNode, 1 ) ;
|
||||
if ( range.EndNode.nodeName.IEquals( 'td' ) )
|
||||
range.SetEnd( range.EndNode, 2 ) ;
|
||||
iterator = new FCKDomRangeIterator( range ) ;
|
||||
iterator.ForceBrBreak = ( state == FCK_TRISTATE_OFF ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now we have two kinds of list groups, groups rooted at a list, and groups rooted at a block limit element.
|
||||
// We either have to build lists or remove lists, for removing a list does not makes sense when we are looking
|
||||
// at the group that's not rooted at lists. So we have three cases to handle.
|
||||
var listsCreated = [] ;
|
||||
while ( listGroups.length > 0 )
|
||||
{
|
||||
var groupObj = listGroups.shift() ;
|
||||
if ( state == FCK_TRISTATE_OFF )
|
||||
{
|
||||
if ( groupObj.root.nodeName.IEquals( ['ul', 'ol'] ) )
|
||||
this._ChangeListType( groupObj, markerObj, listsCreated ) ;
|
||||
else
|
||||
this._CreateList( groupObj, listsCreated ) ;
|
||||
}
|
||||
else if ( state == FCK_TRISTATE_ON && groupObj.root.nodeName.IEquals( ['ul', 'ol'] ) )
|
||||
this._RemoveList( groupObj, markerObj ) ;
|
||||
}
|
||||
|
||||
// For all new lists created, merge adjacent, same type lists.
|
||||
for ( var i = 0 ; i < listsCreated.length ; i++ )
|
||||
{
|
||||
var listNode = listsCreated[i] ;
|
||||
var stopFlag = false ;
|
||||
var currentNode = listNode ;
|
||||
while ( ! stopFlag )
|
||||
{
|
||||
currentNode = currentNode.nextSibling ;
|
||||
if ( currentNode && currentNode.nodeType == 3 && currentNode.nodeValue.search( /^[\n\r\t ]*$/ ) == 0 )
|
||||
continue ;
|
||||
stopFlag = true ;
|
||||
}
|
||||
|
||||
if ( currentNode && currentNode.nodeName.IEquals( this.TagName ) )
|
||||
{
|
||||
currentNode.parentNode.removeChild( currentNode ) ;
|
||||
while ( currentNode.firstChild )
|
||||
listNode.appendChild( currentNode.removeChild( currentNode.firstChild ) ) ;
|
||||
}
|
||||
|
||||
stopFlag = false ;
|
||||
currentNode = listNode ;
|
||||
while ( ! stopFlag )
|
||||
{
|
||||
currentNode = currentNode.previousSibling ;
|
||||
if ( currentNode && currentNode.nodeType == 3 && currentNode.nodeValue.search( /^[\n\r\t ]*$/ ) == 0 )
|
||||
continue ;
|
||||
stopFlag = true ;
|
||||
}
|
||||
if ( currentNode && currentNode.nodeName.IEquals( this.TagName ) )
|
||||
{
|
||||
currentNode.parentNode.removeChild( currentNode ) ;
|
||||
while ( currentNode.lastChild )
|
||||
listNode.insertBefore( currentNode.removeChild( currentNode.lastChild ),
|
||||
listNode.firstChild ) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up, restore selection and update toolbar button states.
|
||||
FCKDomTools.ClearAllMarkers( markerObj ) ;
|
||||
range.MoveToBookmark( bookmark ) ;
|
||||
range.Select() ;
|
||||
|
||||
FCK.Focus() ;
|
||||
FCK.Events.FireEvent( 'OnSelectionChange' ) ;
|
||||
},
|
||||
|
||||
_ChangeListType : function( groupObj, markerObj, listsCreated )
|
||||
{
|
||||
// This case is easy...
|
||||
// 1. Convert the whole list into a one-dimensional array.
|
||||
// 2. Change the list type by modifying the array.
|
||||
// 3. Recreate the whole list by converting the array to a list.
|
||||
// 4. Replace the original list with the recreated list.
|
||||
var listArray = FCKDomTools.ListToArray( groupObj.root, markerObj ) ;
|
||||
var selectedListItems = [] ;
|
||||
for ( var i = 0 ; i < groupObj.contents.length ; i++ )
|
||||
{
|
||||
var itemNode = groupObj.contents[i] ;
|
||||
itemNode = FCKTools.GetElementAscensor( itemNode, 'li' ) ;
|
||||
if ( ! itemNode || itemNode._FCK_ListItem_Processed )
|
||||
continue ;
|
||||
selectedListItems.push( itemNode ) ;
|
||||
FCKDomTools.SetElementMarker( markerObj, itemNode, '_FCK_ListItem_Processed', true ) ;
|
||||
}
|
||||
var fakeParent = FCKTools.GetElementDocument( groupObj.root ).createElement( this.TagName ) ;
|
||||
for ( var i = 0 ; i < selectedListItems.length ; i++ )
|
||||
{
|
||||
var listIndex = selectedListItems[i]._FCK_ListArray_Index ;
|
||||
listArray[listIndex].parent = fakeParent ;
|
||||
}
|
||||
var newList = FCKDomTools.ArrayToList( listArray, markerObj ) ;
|
||||
for ( var i = 0 ; i < newList.listNode.childNodes.length ; i++ )
|
||||
{
|
||||
if ( newList.listNode.childNodes[i].nodeName.IEquals( this.TagName ) )
|
||||
listsCreated.push( newList.listNode.childNodes[i] ) ;
|
||||
}
|
||||
groupObj.root.parentNode.replaceChild( newList.listNode, groupObj.root ) ;
|
||||
},
|
||||
|
||||
_CreateList : function( groupObj, listsCreated )
|
||||
{
|
||||
var contents = groupObj.contents ;
|
||||
var doc = FCKTools.GetElementDocument( groupObj.root ) ;
|
||||
var listContents = [] ;
|
||||
|
||||
// It is possible to have the contents returned by DomRangeIterator to be the same as the root.
|
||||
// e.g. when we're running into table cells.
|
||||
// In such a case, enclose the childNodes of contents[0] into a <div>.
|
||||
if ( contents.length == 1 && contents[0] == groupObj.root )
|
||||
{
|
||||
var divBlock = doc.createElement( 'div' );
|
||||
while ( contents[0].firstChild )
|
||||
divBlock.appendChild( contents[0].removeChild( contents[0].firstChild ) ) ;
|
||||
contents[0].appendChild( divBlock ) ;
|
||||
contents[0] = divBlock ;
|
||||
}
|
||||
|
||||
// Calculate the common parent node of all content blocks.
|
||||
var commonParent = groupObj.contents[0].parentNode ;
|
||||
for ( var i = 0 ; i < contents.length ; i++ )
|
||||
commonParent = FCKDomTools.GetCommonParents( commonParent, contents[i].parentNode ).pop() ;
|
||||
|
||||
// We want to insert things that are in the same tree level only, so calculate the contents again
|
||||
// by expanding the selected blocks to the same tree level.
|
||||
for ( var i = 0 ; i < contents.length ; i++ )
|
||||
{
|
||||
var contentNode = contents[i] ;
|
||||
while ( contentNode.parentNode )
|
||||
{
|
||||
if ( contentNode.parentNode == commonParent )
|
||||
{
|
||||
listContents.push( contentNode ) ;
|
||||
break ;
|
||||
}
|
||||
contentNode = contentNode.parentNode ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( listContents.length < 1 )
|
||||
return ;
|
||||
|
||||
// Insert the list to the DOM tree.
|
||||
var insertAnchor = listContents[listContents.length - 1].nextSibling ;
|
||||
var listNode = doc.createElement( this.TagName ) ;
|
||||
listsCreated.push( listNode ) ;
|
||||
while ( listContents.length )
|
||||
{
|
||||
var contentBlock = listContents.shift() ;
|
||||
var docFrag = doc.createDocumentFragment() ;
|
||||
while ( contentBlock.firstChild )
|
||||
docFrag.appendChild( contentBlock.removeChild( contentBlock.firstChild ) ) ;
|
||||
contentBlock.parentNode.removeChild( contentBlock ) ;
|
||||
var listItem = doc.createElement( 'li' ) ;
|
||||
listItem.appendChild( docFrag ) ;
|
||||
listNode.appendChild( listItem ) ;
|
||||
}
|
||||
commonParent.insertBefore( listNode, insertAnchor ) ;
|
||||
},
|
||||
|
||||
_RemoveList : function( groupObj, markerObj )
|
||||
{
|
||||
// This is very much like the change list type operation.
|
||||
// Except that we're changing the selected items' indent to -1 in the list array.
|
||||
var listArray = FCKDomTools.ListToArray( groupObj.root, markerObj ) ;
|
||||
var selectedListItems = [] ;
|
||||
for ( var i = 0 ; i < groupObj.contents.length ; i++ )
|
||||
{
|
||||
var itemNode = groupObj.contents[i] ;
|
||||
itemNode = FCKTools.GetElementAscensor( itemNode, 'li' ) ;
|
||||
if ( ! itemNode || itemNode._FCK_ListItem_Processed )
|
||||
continue ;
|
||||
selectedListItems.push( itemNode ) ;
|
||||
FCKDomTools.SetElementMarker( markerObj, itemNode, '_FCK_ListItem_Processed', true ) ;
|
||||
}
|
||||
|
||||
var lastListIndex = null ;
|
||||
for ( var i = 0 ; i < selectedListItems.length ; i++ )
|
||||
{
|
||||
var listIndex = selectedListItems[i]._FCK_ListArray_Index ;
|
||||
listArray[listIndex].indent = -1 ;
|
||||
lastListIndex = listIndex ;
|
||||
}
|
||||
|
||||
// After cutting parts of the list out with indent=-1, we still have to maintain the array list
|
||||
// model's nextItem.indent <= currentItem.indent + 1 invariant. Otherwise the array model of the
|
||||
// list cannot be converted back to a real DOM list.
|
||||
for ( var i = lastListIndex + 1; i < listArray.length ; i++ )
|
||||
{
|
||||
if ( listArray[i].indent > listArray[i-1].indent + 1 )
|
||||
{
|
||||
var indentOffset = listArray[i-1].indent + 1 - listArray[i].indent ;
|
||||
var oldIndent = listArray[i].indent ;
|
||||
while ( listArray[i] && listArray[i].indent >= oldIndent)
|
||||
{
|
||||
listArray[i].indent += indentOffset ;
|
||||
i++ ;
|
||||
}
|
||||
i-- ;
|
||||
}
|
||||
}
|
||||
|
||||
var newList = FCKDomTools.ArrayToList( listArray, markerObj ) ;
|
||||
// If groupObj.root is the last element in its parent, or its nextSibling is a <br>, then we should
|
||||
// not add a <br> after the final item. So, check for the cases and trim the <br>.
|
||||
if ( groupObj.root.nextSibling == null || groupObj.root.nextSibling.nodeName.IEquals( 'br' ) )
|
||||
{
|
||||
if ( newList.listNode.lastChild.nodeName.IEquals( 'br' ) )
|
||||
newList.listNode.removeChild( newList.listNode.lastChild ) ;
|
||||
}
|
||||
groupObj.root.parentNode.replaceChild( newList.listNode, groupObj.root ) ;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKNamedCommand Class: represents an internal browser command.
|
||||
*/
|
||||
|
||||
var FCKNamedCommand = function( commandName )
|
||||
{
|
||||
this.Name = commandName ;
|
||||
}
|
||||
|
||||
FCKNamedCommand.prototype.Execute = function()
|
||||
{
|
||||
FCK.ExecuteNamedCommand( this.Name ) ;
|
||||
}
|
||||
|
||||
FCKNamedCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return FCK.GetNamedCommandState( this.Name ) ;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKPastePlainTextCommand Class: represents the
|
||||
* "Paste as Plain Text" command.
|
||||
*/
|
||||
|
||||
var FCKPastePlainTextCommand = function()
|
||||
{
|
||||
this.Name = 'PasteText' ;
|
||||
}
|
||||
|
||||
FCKPastePlainTextCommand.prototype.Execute = function()
|
||||
{
|
||||
FCK.PasteAsPlainText() ;
|
||||
}
|
||||
|
||||
FCKPastePlainTextCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return FCK.GetNamedCommandState( 'Paste' ) ;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKPasteWordCommand Class: represents the "Paste from Word" command.
|
||||
*/
|
||||
|
||||
var FCKPasteWordCommand = function()
|
||||
{
|
||||
this.Name = 'PasteWord' ;
|
||||
}
|
||||
|
||||
FCKPasteWordCommand.prototype.Execute = function()
|
||||
{
|
||||
FCK.PasteFromWord() ;
|
||||
}
|
||||
|
||||
FCKPasteWordCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || FCKConfig.ForcePasteAsPlainText )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
else
|
||||
return FCK.GetNamedCommandState( 'Paste' ) ;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKRemoveFormatCommand Class: controls the execution of a core style. Core
|
||||
* styles are usually represented as buttons in the toolbar., like Bold and
|
||||
* Italic.
|
||||
*/
|
||||
|
||||
var FCKRemoveFormatCommand = function()
|
||||
{
|
||||
this.Name = 'RemoveFormat' ;
|
||||
}
|
||||
|
||||
FCKRemoveFormatCommand.prototype =
|
||||
{
|
||||
Execute : function()
|
||||
{
|
||||
FCKStyles.RemoveAll() ;
|
||||
|
||||
FCK.Focus() ;
|
||||
FCK.Events.FireEvent( 'OnSelectionChange' ) ;
|
||||
},
|
||||
|
||||
GetState : function()
|
||||
{
|
||||
return FCK.EditorWindow ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKShowBlockCommand Class: the "Show Blocks" command.
|
||||
*/
|
||||
|
||||
var FCKShowBlockCommand = function( name, defaultState )
|
||||
{
|
||||
this.Name = name ;
|
||||
if ( defaultState != undefined )
|
||||
this._SavedState = defaultState ;
|
||||
else
|
||||
this._SavedState = null ;
|
||||
}
|
||||
|
||||
FCKShowBlockCommand.prototype.Execute = function()
|
||||
{
|
||||
var state = this.GetState() ;
|
||||
|
||||
if ( state == FCK_TRISTATE_DISABLED )
|
||||
return ;
|
||||
|
||||
var body = FCK.EditorDocument.body ;
|
||||
|
||||
if ( state == FCK_TRISTATE_ON )
|
||||
body.className = body.className.replace( /(^| )FCK__ShowBlocks/g, '' ) ;
|
||||
else
|
||||
body.className += ' FCK__ShowBlocks' ;
|
||||
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
{
|
||||
try
|
||||
{
|
||||
FCK.EditorDocument.selection.createRange().select() ;
|
||||
}
|
||||
catch ( e )
|
||||
{}
|
||||
}
|
||||
else
|
||||
{
|
||||
var focus = FCK.EditorWindow.getSelection().focusNode ;
|
||||
if ( focus.nodeType != 1 )
|
||||
focus = focus.parentNode ;
|
||||
FCKDomTools.ScrollIntoView( focus, false ) ;
|
||||
}
|
||||
|
||||
FCK.Events.FireEvent( 'OnSelectionChange' ) ;
|
||||
}
|
||||
|
||||
FCKShowBlockCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
|
||||
// On some cases FCK.EditorDocument.body is not yet available
|
||||
if ( !FCK.EditorDocument )
|
||||
return FCK_TRISTATE_OFF ;
|
||||
|
||||
if ( /FCK__ShowBlocks(?:\s|$)/.test( FCK.EditorDocument.body.className ) )
|
||||
return FCK_TRISTATE_ON ;
|
||||
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
|
||||
FCKShowBlockCommand.prototype.SaveState = function()
|
||||
{
|
||||
this._SavedState = this.GetState() ;
|
||||
}
|
||||
|
||||
FCKShowBlockCommand.prototype.RestoreState = function()
|
||||
{
|
||||
if ( this._SavedState != null && this.GetState() != this._SavedState )
|
||||
this.Execute() ;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKStyleCommand Class: represents the "Spell Check" command.
|
||||
* (Gecko specific implementation)
|
||||
*/
|
||||
|
||||
var FCKSpellCheckCommand = function()
|
||||
{
|
||||
this.Name = 'SpellCheck' ;
|
||||
this.IsEnabled = ( FCKConfig.SpellChecker == 'SpellerPages' ) ;
|
||||
}
|
||||
|
||||
FCKSpellCheckCommand.prototype.Execute = function()
|
||||
{
|
||||
FCKDialog.OpenDialog( 'FCKDialog_SpellCheck', 'Spell Check', 'dialog/fck_spellerpages.html', 440, 480 ) ;
|
||||
}
|
||||
|
||||
FCKSpellCheckCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return this.IsEnabled ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKStyleCommand Class: represents the "Spell Check" command.
|
||||
* (IE specific implementation)
|
||||
*/
|
||||
|
||||
var FCKSpellCheckCommand = function()
|
||||
{
|
||||
this.Name = 'SpellCheck' ;
|
||||
this.IsEnabled = ( FCKConfig.SpellChecker == 'ieSpell' || FCKConfig.SpellChecker == 'SpellerPages' ) ;
|
||||
}
|
||||
|
||||
FCKSpellCheckCommand.prototype.Execute = function()
|
||||
{
|
||||
switch ( FCKConfig.SpellChecker )
|
||||
{
|
||||
case 'ieSpell' :
|
||||
this._RunIeSpell() ;
|
||||
break ;
|
||||
|
||||
case 'SpellerPages' :
|
||||
FCKDialog.OpenDialog( 'FCKDialog_SpellCheck', 'Spell Check', 'dialog/fck_spellerpages.html', 440, 480 ) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKSpellCheckCommand.prototype._RunIeSpell = function()
|
||||
{
|
||||
try
|
||||
{
|
||||
var oIeSpell = new ActiveXObject( "ieSpell.ieSpellExtension" ) ;
|
||||
oIeSpell.CheckAllLinkedDocuments( FCK.EditorDocument ) ;
|
||||
}
|
||||
catch( e )
|
||||
{
|
||||
if( e.number == -2146827859 )
|
||||
{
|
||||
if ( confirm( FCKLang.IeSpellDownload ) )
|
||||
window.open( FCKConfig.IeSpellDownloadUrl , 'IeSpellDownload' ) ;
|
||||
}
|
||||
else
|
||||
alert( 'Error Loading ieSpell: ' + e.message + ' (' + e.number + ')' ) ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKSpellCheckCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return this.IsEnabled ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKStyleCommand Class: represents the "Style" command.
|
||||
*/
|
||||
|
||||
var FCKStyleCommand = function()
|
||||
{}
|
||||
|
||||
FCKStyleCommand.prototype =
|
||||
{
|
||||
Name : 'Style',
|
||||
|
||||
Execute : function( styleName, styleComboItem )
|
||||
{
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
if ( styleComboItem.Selected )
|
||||
FCK.Styles.RemoveStyle( styleComboItem.Style ) ;
|
||||
else
|
||||
FCK.Styles.ApplyStyle( styleComboItem.Style ) ;
|
||||
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
FCK.Focus() ;
|
||||
FCK.Events.FireEvent( 'OnSelectionChange' ) ;
|
||||
},
|
||||
|
||||
GetState : function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || !FCK.EditorDocument )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
|
||||
if ( FCKSelection.GetType() == 'Control' )
|
||||
{
|
||||
var el = FCKSelection.GetSelectedElement() ;
|
||||
if ( !el || !FCKStyles.CheckHasObjectStyle( el.nodeName.toLowerCase() ) )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
}
|
||||
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKPastePlainTextCommand Class: represents the
|
||||
* "Paste as Plain Text" command.
|
||||
*/
|
||||
|
||||
var FCKTableCommand = function( command )
|
||||
{
|
||||
this.Name = command ;
|
||||
}
|
||||
|
||||
FCKTableCommand.prototype.Execute = function()
|
||||
{
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
if ( ! FCKBrowserInfo.IsGecko )
|
||||
{
|
||||
switch ( this.Name )
|
||||
{
|
||||
case 'TableMergeRight' :
|
||||
return FCKTableHandler.MergeRight() ;
|
||||
case 'TableMergeDown' :
|
||||
return FCKTableHandler.MergeDown() ;
|
||||
}
|
||||
}
|
||||
|
||||
switch ( this.Name )
|
||||
{
|
||||
case 'TableInsertRowAfter' :
|
||||
return FCKTableHandler.InsertRow( false ) ;
|
||||
case 'TableInsertRowBefore' :
|
||||
return FCKTableHandler.InsertRow( true ) ;
|
||||
case 'TableDeleteRows' :
|
||||
return FCKTableHandler.DeleteRows() ;
|
||||
case 'TableInsertColumnAfter' :
|
||||
return FCKTableHandler.InsertColumn( false ) ;
|
||||
case 'TableInsertColumnBefore' :
|
||||
return FCKTableHandler.InsertColumn( true ) ;
|
||||
case 'TableDeleteColumns' :
|
||||
return FCKTableHandler.DeleteColumns() ;
|
||||
case 'TableInsertCellAfter' :
|
||||
return FCKTableHandler.InsertCell( null, false ) ;
|
||||
case 'TableInsertCellBefore' :
|
||||
return FCKTableHandler.InsertCell( null, true ) ;
|
||||
case 'TableDeleteCells' :
|
||||
return FCKTableHandler.DeleteCells() ;
|
||||
case 'TableMergeCells' :
|
||||
return FCKTableHandler.MergeCells() ;
|
||||
case 'TableHorizontalSplitCell' :
|
||||
return FCKTableHandler.HorizontalSplitCell() ;
|
||||
case 'TableVerticalSplitCell' :
|
||||
return FCKTableHandler.VerticalSplitCell() ;
|
||||
case 'TableDelete' :
|
||||
return FCKTableHandler.DeleteTable() ;
|
||||
default :
|
||||
return alert( FCKLang.UnknownCommand.replace( /%1/g, this.Name ) ) ;
|
||||
}
|
||||
}
|
||||
|
||||
FCKTableCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditorDocument != null && FCKSelection.HasAncestorNode( 'TABLE' ) )
|
||||
{
|
||||
switch ( this.Name )
|
||||
{
|
||||
case 'TableHorizontalSplitCell' :
|
||||
case 'TableVerticalSplitCell' :
|
||||
if ( FCKTableHandler.GetSelectedCells().length == 1 )
|
||||
return FCK_TRISTATE_OFF ;
|
||||
else
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
case 'TableMergeCells' :
|
||||
if ( FCKTableHandler.CheckIsSelectionRectangular()
|
||||
&& FCKTableHandler.GetSelectedCells().length > 1 )
|
||||
return FCK_TRISTATE_OFF ;
|
||||
else
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
case 'TableMergeRight' :
|
||||
return FCKTableHandler.GetMergeRightTarget() ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
|
||||
case 'TableMergeDown' :
|
||||
return FCKTableHandler.GetMergeDownTarget() ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
|
||||
default :
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
}
|
||||
else
|
||||
return FCK_TRISTATE_DISABLED;
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* FCKTextColorCommand Class: represents the text color comand. It shows the
|
||||
* color selection panel.
|
||||
*/
|
||||
|
||||
// FCKTextColorCommand Constructor
|
||||
// type: can be 'ForeColor' or 'BackColor'.
|
||||
var FCKTextColorCommand = function( type )
|
||||
{
|
||||
this.Name = type == 'ForeColor' ? 'TextColor' : 'BGColor' ;
|
||||
this.Type = type ;
|
||||
|
||||
var oWindow ;
|
||||
|
||||
if ( FCKBrowserInfo.IsIE )
|
||||
oWindow = window ;
|
||||
else if ( FCK.ToolbarSet._IFrame )
|
||||
oWindow = FCKTools.GetElementWindow( FCK.ToolbarSet._IFrame ) ;
|
||||
else
|
||||
oWindow = window.parent ;
|
||||
|
||||
this._Panel = new FCKPanel( oWindow ) ;
|
||||
this._Panel.AppendStyleSheet( FCKConfig.SkinEditorCSS ) ;
|
||||
this._Panel.MainNode.className = 'FCK_Panel' ;
|
||||
this._CreatePanelBody( this._Panel.Document, this._Panel.MainNode ) ;
|
||||
FCK.ToolbarSet.ToolbarItems.GetItem( this.Name ).RegisterPanel( this._Panel ) ;
|
||||
|
||||
FCKTools.DisableSelection( this._Panel.Document.body ) ;
|
||||
}
|
||||
|
||||
FCKTextColorCommand.prototype.Execute = function( panelX, panelY, relElement )
|
||||
{
|
||||
// Show the Color Panel at the desired position.
|
||||
this._Panel.Show( panelX, panelY, relElement ) ;
|
||||
}
|
||||
|
||||
FCKTextColorCommand.prototype.SetColor = function( color )
|
||||
{
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
var style = FCKStyles.GetStyle( '_FCK_' +
|
||||
( this.Type == 'ForeColor' ? 'Color' : 'BackColor' ) ) ;
|
||||
|
||||
if ( !color || color.length == 0 )
|
||||
FCK.Styles.RemoveStyle( style ) ;
|
||||
else
|
||||
{
|
||||
style.SetVariable( 'Color', color ) ;
|
||||
FCKStyles.ApplyStyle( style ) ;
|
||||
}
|
||||
|
||||
FCKUndo.SaveUndoStep() ;
|
||||
|
||||
FCK.Focus() ;
|
||||
FCK.Events.FireEvent( 'OnSelectionChange' ) ;
|
||||
}
|
||||
|
||||
FCKTextColorCommand.prototype.GetState = function()
|
||||
{
|
||||
if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
|
||||
return FCK_TRISTATE_DISABLED ;
|
||||
return FCK_TRISTATE_OFF ;
|
||||
}
|
||||
|
||||
function FCKTextColorCommand_OnMouseOver()
|
||||
{
|
||||
this.className = 'ColorSelected' ;
|
||||
}
|
||||
|
||||
function FCKTextColorCommand_OnMouseOut()
|
||||
{
|
||||
this.className = 'ColorDeselected' ;
|
||||
}
|
||||
|
||||
function FCKTextColorCommand_OnClick( ev, command, color )
|
||||
{
|
||||
this.className = 'ColorDeselected' ;
|
||||
command.SetColor( color ) ;
|
||||
command._Panel.Hide() ;
|
||||
}
|
||||
|
||||
function FCKTextColorCommand_AutoOnClick( ev, command )
|
||||
{
|
||||
this.className = 'ColorDeselected' ;
|
||||
command.SetColor( '' ) ;
|
||||
command._Panel.Hide() ;
|
||||
}
|
||||
|
||||
function FCKTextColorCommand_MoreOnClick( ev, command )
|
||||
{
|
||||
this.className = 'ColorDeselected' ;
|
||||
command._Panel.Hide() ;
|
||||
FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320,
|
||||
FCKTools.Bind( command, command.SetColor ) ) ;
|
||||
}
|
||||
|
||||
FCKTextColorCommand.prototype._CreatePanelBody = function( targetDocument, targetDiv )
|
||||
{
|
||||
function CreateSelectionDiv()
|
||||
{
|
||||
var oDiv = targetDocument.createElement( "DIV" ) ;
|
||||
oDiv.className = 'ColorDeselected' ;
|
||||
FCKTools.AddEventListenerEx( oDiv, 'mouseover', FCKTextColorCommand_OnMouseOver ) ;
|
||||
FCKTools.AddEventListenerEx( oDiv, 'mouseout', FCKTextColorCommand_OnMouseOut ) ;
|
||||
|
||||
return oDiv ;
|
||||
}
|
||||
|
||||
// Create the Table that will hold all colors.
|
||||
var oTable = targetDiv.appendChild( targetDocument.createElement( "TABLE" ) ) ;
|
||||
oTable.className = 'ForceBaseFont' ; // Firefox 1.5 Bug.
|
||||
oTable.style.tableLayout = 'fixed' ;
|
||||
oTable.cellPadding = 0 ;
|
||||
oTable.cellSpacing = 0 ;
|
||||
oTable.border = 0 ;
|
||||
oTable.width = 150 ;
|
||||
|
||||
var oCell = oTable.insertRow(-1).insertCell(-1) ;
|
||||
oCell.colSpan = 8 ;
|
||||
|
||||
// Create the Button for the "Automatic" color selection.
|
||||
var oDiv = oCell.appendChild( CreateSelectionDiv() ) ;
|
||||
oDiv.innerHTML =
|
||||
'<table cellspacing="0" cellpadding="0" width="100%" border="0">\
|
||||
<tr>\
|
||||
<td><div class="ColorBoxBorder"><div class="ColorBox" style="background-color: #000000"></div></div></td>\
|
||||
<td nowrap width="100%" align="center">' + FCKLang.ColorAutomatic + '</td>\
|
||||
</tr>\
|
||||
</table>' ;
|
||||
|
||||
FCKTools.AddEventListenerEx( oDiv, 'click', FCKTextColorCommand_AutoOnClick, this ) ;
|
||||
|
||||
// Dirty hack for Opera, Safari and Firefox 3.
|
||||
if ( !FCKBrowserInfo.IsIE )
|
||||
oDiv.style.width = '96%' ;
|
||||
|
||||
// Create an array of colors based on the configuration file.
|
||||
var aColors = FCKConfig.FontColors.toString().split(',') ;
|
||||
|
||||
// Create the colors table based on the array.
|
||||
var iCounter = 0 ;
|
||||
while ( iCounter < aColors.length )
|
||||
{
|
||||
var oRow = oTable.insertRow(-1) ;
|
||||
|
||||
for ( var i = 0 ; i < 8 ; i++, iCounter++ )
|
||||
{
|
||||
// The div will be created even if no more colors are available.
|
||||
// Extra divs will be hidden later in the code. (#1597)
|
||||
if ( iCounter < aColors.length )
|
||||
{
|
||||
var colorParts = aColors[iCounter].split('/') ;
|
||||
var colorValue = '#' + colorParts[0] ;
|
||||
var colorName = colorParts[1] || colorValue ;
|
||||
}
|
||||
|
||||
oDiv = oRow.insertCell(-1).appendChild( CreateSelectionDiv() ) ;
|
||||
oDiv.innerHTML = '<div class="ColorBoxBorder"><div class="ColorBox" style="background-color: ' + colorValue + '"></div></div>' ;
|
||||
|
||||
if ( iCounter >= aColors.length )
|
||||
oDiv.style.visibility = 'hidden' ;
|
||||
else
|
||||
FCKTools.AddEventListenerEx( oDiv, 'click', FCKTextColorCommand_OnClick, [ this, colorName ] ) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the Row and the Cell for the "More Colors..." button.
|
||||
if ( FCKConfig.EnableMoreFontColors )
|
||||
{
|
||||
oCell = oTable.insertRow(-1).insertCell(-1) ;
|
||||
oCell.colSpan = 8 ;
|
||||
|
||||
oDiv = oCell.appendChild( CreateSelectionDiv() ) ;
|
||||
oDiv.innerHTML = '<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td nowrap align="center">' + FCKLang.ColorMoreColors + '</td></tr></table>' ;
|
||||
|
||||
FCKTools.AddEventListenerEx( oDiv, 'click', FCKTextColorCommand_MoreOnClick, this ) ;
|
||||
}
|
||||
|
||||
// Dirty hack for Opera, Safari and Firefox 3.
|
||||
if ( !FCKBrowserInfo.IsIE )
|
||||
oDiv.style.width = '96%' ;
|
||||
}
|
||||
56
_cubecart/CubeCart-4.3.0/admin/includes/rte/editor/_source/fckconstants.js
Executable file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Defines some constants used by the editor. These constants are also
|
||||
* globally available in the page where the editor is placed.
|
||||
*/
|
||||
|
||||
// Editor Instance Status.
|
||||
var FCK_STATUS_NOTLOADED = window.parent.FCK_STATUS_NOTLOADED = 0 ;
|
||||
var FCK_STATUS_ACTIVE = window.parent.FCK_STATUS_ACTIVE = 1 ;
|
||||
var FCK_STATUS_COMPLETE = window.parent.FCK_STATUS_COMPLETE = 2 ;
|
||||
|
||||
// Tristate Operations.
|
||||
var FCK_TRISTATE_OFF = window.parent.FCK_TRISTATE_OFF = 0 ;
|
||||
var FCK_TRISTATE_ON = window.parent.FCK_TRISTATE_ON = 1 ;
|
||||
var FCK_TRISTATE_DISABLED = window.parent.FCK_TRISTATE_DISABLED = -1 ;
|
||||
|
||||
// For unknown values.
|
||||
var FCK_UNKNOWN = window.parent.FCK_UNKNOWN = -9 ;
|
||||
|
||||
// Toolbar Items Style.
|
||||
var FCK_TOOLBARITEM_ONLYICON = window.parent.FCK_TOOLBARITEM_ONLYICON = 0 ;
|
||||
var FCK_TOOLBARITEM_ONLYTEXT = window.parent.FCK_TOOLBARITEM_ONLYTEXT = 1 ;
|
||||
var FCK_TOOLBARITEM_ICONTEXT = window.parent.FCK_TOOLBARITEM_ICONTEXT = 2 ;
|
||||
|
||||
// Edit Mode
|
||||
var FCK_EDITMODE_WYSIWYG = window.parent.FCK_EDITMODE_WYSIWYG = 0 ;
|
||||
var FCK_EDITMODE_SOURCE = window.parent.FCK_EDITMODE_SOURCE = 1 ;
|
||||
|
||||
var FCK_IMAGES_PATH = 'images/' ; // Check usage.
|
||||
var FCK_SPACER_PATH = 'images/spacer.gif' ;
|
||||
|
||||
var CTRL = 1000 ;
|
||||
var SHIFT = 2000 ;
|
||||
var ALT = 4000 ;
|
||||
|
||||
var FCK_STYLE_BLOCK = 0 ;
|
||||
var FCK_STYLE_INLINE = 1 ;
|
||||
var FCK_STYLE_OBJECT = 2 ;
|
||||
178
_cubecart/CubeCart-4.3.0/admin/includes/rte/editor/_source/fckeditorapi.js
Executable file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Create the FCKeditorAPI object that is available as a global object in
|
||||
* the page where the editor is placed in.
|
||||
*/
|
||||
|
||||
var FCKeditorAPI ;
|
||||
|
||||
function InitializeAPI()
|
||||
{
|
||||
var oParentWindow = window.parent ;
|
||||
|
||||
if ( !( FCKeditorAPI = oParentWindow.FCKeditorAPI ) )
|
||||
{
|
||||
// Make the FCKeditorAPI object available in the parent window. Use
|
||||
// eval so this core runs in the parent's scope and so it will still be
|
||||
// available if the editor instance is removed ("Can't execute code
|
||||
// from a freed script" error).
|
||||
|
||||
// Note: we check the existence of oEditor.GetParentForm because some external
|
||||
// code (like JSON) can extend the Object prototype and we get then extra oEditor
|
||||
// objects that aren't really FCKeditor instances.
|
||||
var sScript =
|
||||
'window.FCKeditorAPI = {' +
|
||||
'Version : "2.6.3",' +
|
||||
'VersionBuild : "19836",' +
|
||||
'Instances : new Object(),' +
|
||||
|
||||
'GetInstance : function( name )' +
|
||||
'{' +
|
||||
'return this.Instances[ name ];' +
|
||||
'},' +
|
||||
|
||||
'_FormSubmit : function()' +
|
||||
'{' +
|
||||
'for ( var name in FCKeditorAPI.Instances )' +
|
||||
'{' +
|
||||
'var oEditor = FCKeditorAPI.Instances[ name ] ;' +
|
||||
'if ( oEditor.GetParentForm && oEditor.GetParentForm() == this )' +
|
||||
'oEditor.UpdateLinkedField() ;' +
|
||||
'}' +
|
||||
'this._FCKOriginalSubmit() ;' +
|
||||
'},' +
|
||||
|
||||
'_FunctionQueue : {' +
|
||||
'Functions : new Array(),' +
|
||||
'IsRunning : false,' +
|
||||
|
||||
'Add : function( f )' +
|
||||
'{' +
|
||||
'this.Functions.push( f );' +
|
||||
'if ( !this.IsRunning )' +
|
||||
'this.StartNext();' +
|
||||
'},' +
|
||||
|
||||
'StartNext : function()' +
|
||||
'{' +
|
||||
'var aQueue = this.Functions ;' +
|
||||
'if ( aQueue.length > 0 )' +
|
||||
'{' +
|
||||
'this.IsRunning = true;' +
|
||||
'aQueue[0].call();' +
|
||||
'}' +
|
||||
'else ' +
|
||||
'this.IsRunning = false;' +
|
||||
'},' +
|
||||
|
||||
'Remove : function( f )' +
|
||||
'{' +
|
||||
'var aQueue = this.Functions;' +
|
||||
'var i = 0, fFunc;' +
|
||||
'while( (fFunc = aQueue[ i ]) )' +
|
||||
'{' +
|
||||
'if ( fFunc == f )' +
|
||||
'aQueue.splice( i,1 );' +
|
||||
'i++ ;' +
|
||||
'}' +
|
||||
'this.StartNext();' +
|
||||
'}' +
|
||||
'}' +
|
||||
'}' ;
|
||||
|
||||
// In IE, the "eval" function is not always available (it works with
|
||||
// the JavaScript samples, but not with the ASP ones, for example).
|
||||
// So, let's use the execScript instead.
|
||||
if ( oParentWindow.execScript )
|
||||
oParentWindow.execScript( sScript, 'JavaScript' ) ;
|
||||
else
|
||||
{
|
||||
if ( FCKBrowserInfo.IsGecko10 )
|
||||
{
|
||||
// FF 1.0.4 gives an error with the request bellow. The
|
||||
// following seams to work well.
|
||||
eval.call( oParentWindow, sScript ) ;
|
||||
}
|
||||
else if( FCKBrowserInfo.IsAIR )
|
||||
{
|
||||
FCKAdobeAIR.FCKeditorAPI_Evaluate( oParentWindow, sScript ) ;
|
||||
}
|
||||
else if ( FCKBrowserInfo.IsSafari )
|
||||
{
|
||||
// oParentWindow.eval in Safari and Gran Paradiso executes in the calling window
|
||||
// environment, instead of the parent one. The following should make it work.
|
||||
var oParentDocument = oParentWindow.document ;
|
||||
var eScript = oParentDocument.createElement('script') ;
|
||||
eScript.appendChild( oParentDocument.createTextNode( sScript ) ) ;
|
||||
oParentDocument.documentElement.appendChild( eScript ) ;
|
||||
}
|
||||
else
|
||||
oParentWindow.eval( sScript ) ;
|
||||
}
|
||||
|
||||
FCKeditorAPI = oParentWindow.FCKeditorAPI ;
|
||||
|
||||
// The __Instances properly has been changed to the public Instances,
|
||||
// but we should still have the "deprecated" version of it.
|
||||
FCKeditorAPI.__Instances = FCKeditorAPI.Instances ;
|
||||
}
|
||||
|
||||
// Add the current instance to the FCKeditorAPI's instances collection.
|
||||
FCKeditorAPI.Instances[ FCK.Name ] = FCK ;
|
||||
}
|
||||
|
||||
// Attach to the form onsubmit event and to the form.submit().
|
||||
function _AttachFormSubmitToAPI()
|
||||
{
|
||||
// Get the linked field form.
|
||||
var oForm = FCK.GetParentForm() ;
|
||||
|
||||
if ( oForm )
|
||||
{
|
||||
// Attach to the onsubmit event.
|
||||
FCKTools.AddEventListener( oForm, 'submit', FCK.UpdateLinkedField ) ;
|
||||
|
||||
// IE sees oForm.submit function as an 'object'.
|
||||
if ( !oForm._FCKOriginalSubmit && ( typeof( oForm.submit ) == 'function' || ( !oForm.submit.tagName && !oForm.submit.length ) ) )
|
||||
{
|
||||
// Save the original submit.
|
||||
oForm._FCKOriginalSubmit = oForm.submit ;
|
||||
|
||||
// Create our replacement for the submit.
|
||||
oForm.submit = FCKeditorAPI._FormSubmit ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function FCKeditorAPI_Cleanup()
|
||||
{
|
||||
if ( window.FCKConfig && FCKConfig.MsWebBrowserControlCompat
|
||||
&& !window.FCKUnloadFlag )
|
||||
return ;
|
||||
delete FCKeditorAPI.Instances[ FCK.Name ] ;
|
||||
}
|
||||
function FCKeditorAPI_ConfirmCleanup()
|
||||
{
|
||||
if ( window.FCKConfig && FCKConfig.MsWebBrowserControlCompat )
|
||||
window.FCKUnloadFlag = true ;
|
||||
}
|
||||
FCKTools.AddEventListener( window, 'unload', FCKeditorAPI_Cleanup ) ;
|
||||
FCKTools.AddEventListener( window, 'beforeunload', FCKeditorAPI_ConfirmCleanup) ;
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
||||
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
|
||||
*
|
||||
* == BEGIN LICENSE ==
|
||||
*
|
||||
* Licensed under the terms of any of the following licenses at your
|
||||
* choice:
|
||||
*
|
||||
* - GNU General Public License Version 2 or later (the "GPL")
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
*
|
||||
* == END LICENSE ==
|
||||
*
|
||||
* Extensions to the JavaScript Core.
|
||||
*
|
||||
* All custom extensions functions are PascalCased to differ from the standard
|
||||
* camelCased ones.
|
||||
*/
|
||||
|
||||
String.prototype.Contains = function( textToCheck )
|
||||
{
|
||||
return ( this.indexOf( textToCheck ) > -1 ) ;
|
||||
}
|
||||
|
||||
String.prototype.Equals = function()
|
||||
{
|
||||
var aArgs = arguments ;
|
||||
|
||||
// The arguments could also be a single array.
|
||||
if ( aArgs.length == 1 && aArgs[0].pop )
|
||||
aArgs = aArgs[0] ;
|
||||
|
||||
for ( var i = 0 ; i < aArgs.length ; i++ )
|
||||
{
|
||||
if ( this == aArgs[i] )
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
String.prototype.IEquals = function()
|
||||
{
|
||||
var thisUpper = this.toUpperCase() ;
|
||||
|
||||
var aArgs = arguments ;
|
||||
|
||||
// The arguments could also be a single array.
|
||||
if ( aArgs.length == 1 && aArgs[0].pop )
|
||||
aArgs = aArgs[0] ;
|
||||
|
||||
for ( var i = 0 ; i < aArgs.length ; i++ )
|
||||
{
|
||||
if ( thisUpper == aArgs[i].toUpperCase() )
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
String.prototype.ReplaceAll = function( searchArray, replaceArray )
|
||||
{
|
||||
var replaced = this ;
|
||||
|
||||
for ( var i = 0 ; i < searchArray.length ; i++ )
|
||||
{
|
||||
replaced = replaced.replace( searchArray[i], replaceArray[i] ) ;
|
||||
}
|
||||
|
||||
return replaced ;
|
||||
}
|
||||
|
||||
String.prototype.StartsWith = function( value )
|
||||
{
|
||||
return ( this.substr( 0, value.length ) == value ) ;
|
||||
}
|
||||
|
||||
// Extends the String object, creating a "EndsWith" method on it.
|
||||
String.prototype.EndsWith = function( value, ignoreCase )
|
||||
{
|
||||
var L1 = this.length ;
|
||||
var L2 = value.length ;
|
||||
|
||||
if ( L2 > L1 )
|
||||
return false ;
|
||||
|
||||
if ( ignoreCase )
|
||||
{
|
||||
var oRegex = new RegExp( value + '$' , 'i' ) ;
|
||||
return oRegex.test( this ) ;
|
||||
}
|
||||
else
|
||||
return ( L2 == 0 || this.substr( L1 - L2, L2 ) == value ) ;
|
||||
}
|
||||
|
||||
String.prototype.Remove = function( start, length )
|
||||
{
|
||||
var s = '' ;
|
||||
|
||||
if ( start > 0 )
|
||||
s = this.substring( 0, start ) ;
|
||||
|
||||
if ( start + length < this.length )
|
||||
s += this.substring( start + length , this.length ) ;
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
String.prototype.Trim = function()
|
||||
{
|
||||
// We are not using \s because we don't want "non-breaking spaces to be caught".
|
||||
return this.replace( /(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '' ) ;
|
||||
}
|
||||
|
||||
String.prototype.LTrim = function()
|
||||
{
|
||||
// We are not using \s because we don't want "non-breaking spaces to be caught".
|
||||
return this.replace( /^[ \t\n\r]*/g, '' ) ;
|
||||
}
|
||||
|
||||
String.prototype.RTrim = function()
|
||||
{
|
||||
// We are not using \s because we don't want "non-breaking spaces to be caught".
|
||||
return this.replace( /[ \t\n\r]*$/g, '' ) ;
|
||||
}
|
||||
|
||||
String.prototype.ReplaceNewLineChars = function( replacement )
|
||||
{
|
||||
return this.replace( /\n/g, replacement ) ;
|
||||
}
|
||||
|
||||
String.prototype.Replace = function( regExp, replacement, thisObj )
|
||||
{
|
||||
if ( typeof replacement == 'function' )
|
||||
{
|
||||
return this.replace( regExp,
|
||||
function()
|
||||
{
|
||||
return replacement.apply( thisObj || this, arguments ) ;
|
||||
} ) ;
|
||||
}
|
||||
else
|
||||
return this.replace( regExp, replacement ) ;
|
||||
}
|
||||
|
||||
Array.prototype.AddItem = function( item )
|
||||
{
|
||||
var i = this.length ;
|
||||
this[ i ] = item ;
|
||||
return i ;
|
||||
}
|
||||
|
||||
Array.prototype.IndexOf = function( value )
|
||||
{
|
||||
for ( var i = 0 ; i < this.length ; i++ )
|
||||
{
|
||||
if ( this[i] == value )
|
||||
return i ;
|
||||
}
|
||||
return -1 ;
|
||||
}
|
||||