natural search in list pages

This commit is contained in:
Cédric Salvador
2013-09-10 16:43:06 +02:00
parent 9826b202e9
commit d9a26d0aa9
422 changed files with 126638 additions and 126593 deletions

View File

@@ -1,169 +1,169 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
sitemap_gen.py example configuration script sitemap_gen.py example configuration script
This file specifies a set of sample input parameters for the This file specifies a set of sample input parameters for the
sitemap_gen.py client. sitemap_gen.py client.
You should copy this file into "config.xml" and modify it for You should copy this file into "config.xml" and modify it for
your server. your server.
********************************************************* --> ********************************************************* -->
<!-- ** MODIFY ** <!-- ** MODIFY **
The "site" node describes your basic web site. The "site" node describes your basic web site.
Required attributes: Required attributes:
base_url - the top-level URL of the site being mapped base_url - the top-level URL of the site being mapped
store_into - the webserver path to the desired output file. store_into - the webserver path to the desired output file.
This should end in '.xml' or '.xml.gz' This should end in '.xml' or '.xml.gz'
(the script will create this file) (the script will create this file)
Optional attributes: Optional attributes:
verbose - an integer from 0 (quiet) to 3 (noisy) for verbose - an integer from 0 (quiet) to 3 (noisy) for
how much diagnostic output the script gives how much diagnostic output the script gives
suppress_search_engine_notify="1" suppress_search_engine_notify="1"
- disables notifying search engines about the new map - disables notifying search engines about the new map
(same as the "testing" command-line argument.) (same as the "testing" command-line argument.)
default_encoding default_encoding
- names a character encoding to use for URLs and - names a character encoding to use for URLs and
file paths. (Example: "UTF-8") file paths. (Example: "UTF-8")
--> -->
<site <site
base_url="http://wiki.dolibarr.org/" base_url="http://wiki.dolibarr.org/"
store_into="sitemap-wiki-bing.xml.gz" store_into="sitemap-wiki-bing.xml.gz"
verbose="1" verbose="1"
> >
<!-- ******************************************************** <!-- ********************************************************
INPUTS INPUTS
All the various nodes in this section control where the script All the various nodes in this section control where the script
looks to find URLs. looks to find URLs.
MODIFY or DELETE these entries as appropriate for your server. MODIFY or DELETE these entries as appropriate for your server.
********************************************************* --> ********************************************************* -->
<!-- ** MODIFY or DELETE ** <!-- ** MODIFY or DELETE **
"url" nodes specify individual URLs to include in the map. "url" nodes specify individual URLs to include in the map.
Required attributes: Required attributes:
href - the URL href - the URL
Optional attributes: Optional attributes:
lastmod - timestamp of last modification (ISO8601 format) lastmod - timestamp of last modification (ISO8601 format)
changefreq - how often content at this URL is usually updated changefreq - how often content at this URL is usually updated
priority - value 0.0 to 1.0 of relative importance in your site priority - value 0.0 to 1.0 of relative importance in your site
--> -->
<!-- <!--
<url href="http://www.example.com/stats?q=name" /> <url href="http://www.example.com/stats?q=name" />
<url <url
href="http://www.example.com/stats?q=age" href="http://www.example.com/stats?q=age"
lastmod="2004-11-14T01:00:00-07:00" lastmod="2004-11-14T01:00:00-07:00"
changefreq="yearly" changefreq="yearly"
priority="0.3" priority="0.3"
/> />
--> -->
<!-- ** MODIFY or DELETE ** <!-- ** MODIFY or DELETE **
"urllist" nodes name text files with lists of URLs. "urllist" nodes name text files with lists of URLs.
An example file "example_urllist.txt" is provided. An example file "example_urllist.txt" is provided.
Required attributes: Required attributes:
path - path to the file path - path to the file
Optional attributes: Optional attributes:
encoding - encoding of the file if not US-ASCII encoding - encoding of the file if not US-ASCII
--> -->
<urllist path="urllist-wiki.txt" encoding="UTF-8" /> <urllist path="urllist-wiki.txt" encoding="UTF-8" />
<!-- ** MODIFY or DELETE ** <!-- ** MODIFY or DELETE **
"directory" nodes tell the script to walk the file system "directory" nodes tell the script to walk the file system
and include all files and directories in the Sitemap. and include all files and directories in the Sitemap.
Required attributes: Required attributes:
path - path to begin walking from path - path to begin walking from
url - URL equivalent of that path url - URL equivalent of that path
Optional attributes: Optional attributes:
default_file - name of the index or default file for directory URLs default_file - name of the index or default file for directory URLs
--> -->
<!-- <!--
<directory path="/var/www/icons" url="http://www.example.com/images/" /> <directory path="/var/www/icons" url="http://www.example.com/images/" />
<directory <directory
path="/var/www/docroot" path="/var/www/docroot"
url="http://www.example.com/" url="http://www.example.com/"
default_file="index.html" default_file="index.html"
/> />
--> -->
<!-- ** MODIFY or DELETE ** <!-- ** MODIFY or DELETE **
"accesslog" nodes tell the script to scan webserver log files to "accesslog" nodes tell the script to scan webserver log files to
extract URLs on your site. Both Common Logfile Format (Apache's default extract URLs on your site. Both Common Logfile Format (Apache's default
logfile) and Extended Logfile Format (IIS's default logfile) can be read. logfile) and Extended Logfile Format (IIS's default logfile) can be read.
Required attributes: Required attributes:
path - path to the file path - path to the file
Optional attributes: Optional attributes:
encoding - encoding of the file if not US-ASCII encoding - encoding of the file if not US-ASCII
--> -->
<!-- <!--
<accesslog path="/etc/httpd/logs/access.log" encoding="UTF-8" /> <accesslog path="/etc/httpd/logs/access.log" encoding="UTF-8" />
<accesslog path="/etc/httpd/logs/access.log.0" encoding="UTF-8" /> <accesslog path="/etc/httpd/logs/access.log.0" encoding="UTF-8" />
<accesslog path="/etc/httpd/logs/access.log.1.gz" encoding="UTF-8" /> <accesslog path="/etc/httpd/logs/access.log.1.gz" encoding="UTF-8" />
--> -->
<!-- ** MODIFY or DELETE ** <!-- ** MODIFY or DELETE **
"sitemap" nodes tell the script to scan other Sitemap files. This can "sitemap" nodes tell the script to scan other Sitemap files. This can
be useful to aggregate the results of multiple runs of this script into be useful to aggregate the results of multiple runs of this script into
a single Sitemap. a single Sitemap.
Required attributes: Required attributes:
path - path to the file path - path to the file
--> -->
<!-- <!--
<sitemap path="/var/www/docroot/subpath/sitemap.xml" /> <sitemap path="/var/www/docroot/subpath/sitemap.xml" />
--> -->
<!-- ******************************************************** <!-- ********************************************************
FILTERS FILTERS
Filters specify wild-card patterns that the script compares Filters specify wild-card patterns that the script compares
against all URLs it finds. Filters can be used to exclude against all URLs it finds. Filters can be used to exclude
certain URLs from your Sitemap, for instance if you have certain URLs from your Sitemap, for instance if you have
hidden content that you hope the search engines don't find. hidden content that you hope the search engines don't find.
Filters can be either type="wildcard", which means standard Filters can be either type="wildcard", which means standard
path wildcards (* and ?) are used to compare against URLs, path wildcards (* and ?) are used to compare against URLs,
or type="regexp", which means regular expressions are used or type="regexp", which means regular expressions are used
to compare. to compare.
Filters are applied in the order specified in this file. Filters are applied in the order specified in this file.
An action="drop" filter causes exclusion of matching URLs. An action="drop" filter causes exclusion of matching URLs.
An action="pass" filter causes inclusion of matching URLs, An action="pass" filter causes inclusion of matching URLs,
shortcutting any other later filters that might also match. shortcutting any other later filters that might also match.
If no filter at all matches a URL, the URL will be included. If no filter at all matches a URL, the URL will be included.
Together you can build up fairly complex rules. Together you can build up fairly complex rules.
The default action is "drop". The default action is "drop".
The default type is "wildcard". The default type is "wildcard".
You can MODIFY or DELETE these entries as appropriate for You can MODIFY or DELETE these entries as appropriate for
your site. However, unlike above, the example entries in your site. However, unlike above, the example entries in
this section are not contrived and may be useful to you as this section are not contrived and may be useful to you as
they are. they are.
********************************************************* --> ********************************************************* -->
<!-- Exclude URLs that end with a '~' (IE: emacs backup files) --> <!-- Exclude URLs that end with a '~' (IE: emacs backup files) -->
<filter action="drop" type="wildcard" pattern="*~" /> <filter action="drop" type="wildcard" pattern="*~" />
<!-- Exclude URLs within UNIX-style hidden files or directories --> <!-- Exclude URLs within UNIX-style hidden files or directories -->
<filter action="drop" type="regexp" pattern="/\.[^/]*" /> <filter action="drop" type="regexp" pattern="/\.[^/]*" />
<filter action="drop" type="regexp" pattern="title=" /> <filter action="drop" type="regexp" pattern="title=" />
</site> </site>

View File

@@ -2,6 +2,7 @@
/* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org> /* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -115,9 +116,13 @@ if ($catid > 0) $sql.= " AND cs.fk_categorie = ".$catid;
if ($catid == -2) $sql.= " AND cs.fk_categorie IS NULL"; if ($catid == -2) $sql.= " AND cs.fk_categorie IS NULL";
if ($search_categ > 0) $sql.= " AND cs.fk_categorie = ".$search_categ; if ($search_categ > 0) $sql.= " AND cs.fk_categorie = ".$search_categ;
if ($search_categ == -2) $sql.= " AND cs.fk_categorie IS NULL"; if ($search_categ == -2) $sql.= " AND cs.fk_categorie IS NULL";
if ($search_nom) $sql.= " AND s.nom LIKE '%".$db->escape($search_nom)."%'"; if ($search_nom) {
$sql .= natural_search(array('s.nom'), $search_nom);
}
if ($search_zipcode) $sql.= " AND s.zip LIKE '".$db->escape($search_zipcode)."%'"; if ($search_zipcode) $sql.= " AND s.zip LIKE '".$db->escape($search_zipcode)."%'";
if ($search_town) $sql.= " AND s.town LIKE '%".$db->escape($search_town)."%'"; if ($search_town) {
$sql .= natural_search(array('s.town'), $search_town);
}
if ($search_code) $sql.= " AND s.code_client LIKE '%".$db->escape($search_code)."%'"; if ($search_code) $sql.= " AND s.code_client LIKE '%".$db->escape($search_code)."%'";
if ($search_compta) $sql.= " AND s.code_compta LIKE '%".$db->escape($search_compta)."%'"; if ($search_compta) $sql.= " AND s.code_compta LIKE '%".$db->escape($search_compta)."%'";
// Insert sale filter // Insert sale filter

View File

@@ -8,6 +8,7 @@
* Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2010-2011 Philippe Grand <philippe.grand@atoo-net.com> * Copyright (C) 2010-2011 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr> * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -160,21 +161,17 @@ if (! $user->rights->societe->client->voir && ! $socid) //restriction
{ {
$sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
} }
if ($search_town) //restriction if ($search_town) {//restriction
{ $sql .= natural_search(array('s.town'), $search_town);
$sql.= " AND s.town LIKE '%".$db->escape(trim($search_town))."%'";
} }
if ($search_ref) if ($search_ref) {
{ $sql .= natural_search(array('p.ref'), $search_ref);
$sql.= " AND p.ref LIKE '%".$db->escape(trim($search_ref))."%'";
} }
if ($search_refcustomer) if ($search_refcustomer) {
{ $sql .= natural_search(array('p.ref_client'), $search_refcustomer);
$sql.= " AND p.ref_client LIKE '%".$db->escape(trim($search_refcustomer))."%'";
} }
if ($search_societe) if ($search_societe) {
{ $sql .= natural_search(array('s.nom'), $search_societe);
$sql.= " AND s.nom LIKE '%".$db->escape(trim($search_societe))."%'";
} }
if ($search_author) if ($search_author)
{ {
@@ -184,7 +181,13 @@ if ($search_montant_ht)
{ {
$sql.= " AND p.total_ht='".$db->escape(price2num(trim($search_montant_ht)))."'"; $sql.= " AND p.total_ht='".$db->escape(price2num(trim($search_montant_ht)))."'";
} }
if ($sall) $sql.= " AND (s.nom LIKE '%".$db->escape($sall)."%' OR p.note_private LIKE '%".$db->escape($sall)."%' OR pd.description LIKE '%".$db->escape($sall)."%')"; if ($sall) {
/*$scrit = explode(' ', $sall);
foreach ($scrit as $crit) {
$sql.= " AND (s.nom LIKE '%".$db->escape($crit)."%' OR p.note LIKE '%".$db->escape($crit)."%' OR pd.description LIKE '%".$db->escape($crit)."%')";
}*/
$sql .= natural_search(array('s.nom', 'p.note_private', 'pd.description'), $sall);
}
if ($socid) $sql.= ' AND s.rowid = '.$socid; if ($socid) $sql.= ' AND s.rowid = '.$socid;
if ($viewstatut <> '') if ($viewstatut <> '')
{ {
@@ -289,7 +292,7 @@ if ($result)
print '<td class="liste_titre" align="left">'; print '<td class="liste_titre" align="left">';
print '<input class="flat" type="text" size="16" name="search_societe" value="'.$search_societe.'">'; print '<input class="flat" type="text" size="16" name="search_societe" value="'.$search_societe.'">';
print '</td>'; print '</td>';
print '<td>&nbsp;</td>'; print '<td class="liste_titre"><input class="flat" type="text" size="16" name="search_town" value="'.$search_town.'"></td>';
print '<td class="liste_titre">'; print '<td class="liste_titre">';
print '<input class="flat" size="10" type="text" name="search_refcustomer" value="'.$search_refcustomer.'">'; print '<input class="flat" size="10" type="text" name="search_refcustomer" value="'.$search_refcustomer.'">';
print '</td>'; print '</td>';

View File

@@ -4,6 +4,7 @@
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2011 Philippe Grand <philippe.grand@atoo-net.com> * Copyright (C) 2011 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro> * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -193,10 +194,16 @@ if ($catid > 0) $sql.= " AND cs.fk_categorie = ".$catid;
if ($catid == -2) $sql.= " AND cs.fk_categorie IS NULL"; if ($catid == -2) $sql.= " AND cs.fk_categorie IS NULL";
if ($search_categ > 0) $sql.= " AND cs.fk_categorie = ".$search_categ; if ($search_categ > 0) $sql.= " AND cs.fk_categorie = ".$search_categ;
if ($search_categ == -2) $sql.= " AND cs.fk_categorie IS NULL"; if ($search_categ == -2) $sql.= " AND cs.fk_categorie IS NULL";
if ($search_nom) $sql .= " AND s.nom LIKE '%".$db->escape(strtolower($search_nom))."%'"; if ($search_nom) {
$sql .= natural_search(array('s.nom'), $search_nom);
}
if ($search_zipcode) $sql .= " AND s.zip LIKE '".$db->escape(strtolower($search_zipcode))."%'"; if ($search_zipcode) $sql .= " AND s.zip LIKE '".$db->escape(strtolower($search_zipcode))."%'";
if ($search_town) $sql .= " AND s.town LIKE '%".$db->escape(strtolower($search_town))."%'"; if ($search_town) {
if ($search_state) $sql .= " AND d.nom LIKE '%".$db->escape(strtolower($search_state))."%'"; $sql .= natural_search(array('s.town'), $search_town);
}
if ($search_state) {
$sql .= natural_search(array('d.nom'), $search_state);
}
if ($search_datec) $sql .= " AND s.datec LIKE '%".$db->escape($search_datec)."%'"; if ($search_datec) $sql .= " AND s.datec LIKE '%".$db->escape($search_datec)."%'";
// Insert levels filters // Insert levels filters
if ($search_levels) if ($search_levels)
@@ -208,9 +215,8 @@ if ($search_sale)
{ {
$sql .= " AND sc.fk_user = ".$db->escape($search_sale); $sql .= " AND sc.fk_user = ".$db->escape($search_sale);
} }
if ($socname) if ($socname) {
{ $sql .= natural_search(array('s.nom'), $search_nom);
$sql .= " AND s.nom LIKE '%".$db->escape($socname)."%'";
$sortfield = "s.nom"; $sortfield = "s.nom";
$sortorder = "ASC"; $sortorder = "ASC";
} }

View File

@@ -5,6 +5,7 @@
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2012 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2012 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2013 Christophe Battarel <christophe.battarel@altairis.fr> * Copyright (C) 2013 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -125,13 +126,12 @@ $sql.= ' WHERE c.fk_soc = s.rowid';
$sql.= ' AND c.entity = '.$conf->entity; $sql.= ' AND c.entity = '.$conf->entity;
if ($socid) $sql.= ' AND s.rowid = '.$socid; if ($socid) $sql.= ' AND s.rowid = '.$socid;
if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
if ($sref) if ($sref) {
{ $sql .= natural_search(array('c.ref'), $sref);
$sql.= " AND c.ref LIKE '%".$db->escape($sref)."%'";
} }
if ($sall) if ($sall)
{ {
$sql.= " AND (c.ref LIKE '%".$db->escape($sall)."%' OR c.note LIKE '%".$db->escape($sall)."%')"; $sql .= natural_search(array('c.ref', 'c.note_private'), $sall);
} }
if ($viewstatut <> '') if ($viewstatut <> '')
{ {
@@ -187,7 +187,7 @@ else if ($deliveryyear > 0)
} }
if (!empty($snom)) if (!empty($snom))
{ {
$sql.= ' AND s.nom LIKE \'%'.$db->escape($snom).'%\''; $sql .= natural_search(array('s.nom'), $snom);
} }
if (!empty($sref_client)) if (!empty($sref_client))
{ {

View File

@@ -2,6 +2,7 @@
/* Copyright (C) 2001-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> /* Copyright (C) 2001-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -75,11 +76,11 @@ if (trim($search_ref) != '')
} }
if (trim($search_company) != '') if (trim($search_company) != '')
{ {
$sql.= ' AND d.societe LIKE \'%'.$db->escape(trim($search_company)) . '%\''; $sql .= natural_search(array('d.societe'), $search_company);
} }
if (trim($search_name) != '') if (trim($search_name) != '')
{ {
$sql.= ' AND d.lastname LIKE \'%'.$db->escape(trim($search_name)) . '%\' OR d.firstname LIKE \'%'.$db->escape(trim($search_name)) . '%\''; $sql .= natural_search(array('d.lastname', 'd.firstname'), $search_name);
} }
$sql.= $db->order($sortfield,$sortorder); $sql.= $db->order($sortfield,$sortorder);
$sql.= $db->plimit($limit+1, $offset); $sql.= $db->plimit($limit+1, $offset);

View File

@@ -8,6 +8,7 @@
* Copyright (C) 2010-2012 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2010-2012 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr> * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro> * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -174,11 +175,11 @@ if ($filtre)
} }
if ($search_ref) if ($search_ref)
{ {
$sql.= ' AND f.facnumber LIKE \'%'.$db->escape(trim($search_ref)).'%\''; $sql .= natural_search(array('f.facnumber'), $search_ref);
} }
if ($search_societe) if ($search_societe)
{ {
$sql.= ' AND s.nom LIKE \'%'.$db->escape(trim($search_societe)).'%\''; $sql .= natural_search(array('s.nom'), $search_societe);
} }
if ($search_montant_ht) if ($search_montant_ht)
{ {
@@ -219,7 +220,7 @@ if (! $sall)
} }
else else
{ {
$sql.= ' AND (s.nom LIKE \'%'.$db->escape($sall).'%\' OR f.facnumber LIKE \'%'.$db->escape($sall).'%\' OR f.note LIKE \'%'.$db->escape($sall).'%\' OR fd.description LIKE \'%'.$db->escape($sall).'%\')'; $sql .= natural_search(array('s.nom', 'f.facnumber', 'f.note_public', 'fd.description'), $sall);
} }
$sql.= ' ORDER BY '; $sql.= ' ORDER BY ';
$listfield=explode(',',$sortfield); $listfield=explode(',',$sortfield);

View File

@@ -2,6 +2,7 @@
/* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org> /* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2009 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -112,7 +113,7 @@ else
if (GETPOST("search_account") > 0) $sql .=" AND b.fk_account=".GETPOST("search_account",'int'); if (GETPOST("search_account") > 0) $sql .=" AND b.fk_account=".GETPOST("search_account",'int');
if (GETPOST("search_paymenttype") != "") $sql .=" AND c.code='".GETPOST("search_paymenttype")."'"; if (GETPOST("search_paymenttype") != "") $sql .=" AND c.code='".GETPOST("search_paymenttype")."'";
if (GETPOST("search_amount")) $sql .=" AND p.amount=".price2num(GETPOST("search_amount")); if (GETPOST("search_amount")) $sql .=" AND p.amount=".price2num(GETPOST("search_amount"));
if (GETPOST("search_company")) $sql .=" AND s.nom LIKE '%".$db->escape(GETPOST("search_company"))."%'"; if (GETPOST("search_company")) $sql .= natural_search(array('s.nom'), GETPOST('search_company'));
} }
$sql.= $db->order($sortfield,$sortorder); $sql.= $db->order($sortfield,$sortorder);
$sql.= $db->plimit($limit+1, $offset); $sql.= $db->plimit($limit+1, $offset);

View File

@@ -4,6 +4,7 @@
* Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2013 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr> * Copyright (C) 2013 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -148,21 +149,17 @@ else
if ($search_categ > 0) $sql.= " AND cs.fk_categorie = ".$search_categ; if ($search_categ > 0) $sql.= " AND cs.fk_categorie = ".$search_categ;
if ($search_categ == -2) $sql.= " AND cs.fk_categorie IS NULL"; if ($search_categ == -2) $sql.= " AND cs.fk_categorie IS NULL";
if ($search_lastname) // filter on lastname if ($search_lastname) { // filter on lastname
{ $sql .= natural_search(array('p.lastname'), $search_lastname);
$sql .= " AND p.lastname LIKE '%".$db->escape($search_lastname)."%'";
} }
if ($search_firstname) // filter on firstname if ($search_firstname) { // filter on firstname
{ $sql .= natural_search(array('p.firstname'), $search_firstname);
$sql .= " AND p.firstname LIKE '%".$db->escape($search_firstname)."%'";
} }
if ($search_societe) // filtre sur la societe if ($search_societe) { // filtre sur la societe
{ $sql .= natural_search(array('s.nom'), $search_societe);
$sql .= " AND s.nom LIKE '%".$db->escape($search_societe)."%'";
} }
if (strlen($search_poste)) // filtre sur la societe if (strlen($search_poste)) { // filtre sur la societe
{ $sql .= natural_search(array('p.poste'), $search_poste);
$sql .= " AND p.poste LIKE '%".$db->escape($search_poste)."%'";
} }
if (strlen($search_phone)) if (strlen($search_phone))
{ {
@@ -206,11 +203,7 @@ else if ($type == "p") // filtre sur type
} }
if ($sall) if ($sall)
{ {
// For natural search $sql .= natural_search(array('p.lastname', 'p.firstname', 'p.email'), $sall);
$scrit = explode(' ', $sall);
foreach ($scrit as $crit) {
$sql .= " AND (p.lastname LIKE '%".$db->escape($crit)."%' OR p.firstname LIKE '%".$db->escape($crit)."%' OR p.email LIKE '%".$db->escape($crit)."%')";
}
} }
if (! empty($socid)) if (! empty($socid))
{ {

View File

@@ -2,6 +2,7 @@
/* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> /* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -79,9 +80,15 @@ $sql.= " WHERE c.fk_soc = s.rowid ";
$sql.= " AND c.entity = ".$conf->entity; $sql.= " AND c.entity = ".$conf->entity;
if ($socid) $sql.= " AND s.rowid = ".$socid; if ($socid) $sql.= " AND s.rowid = ".$socid;
if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
if ($search_nom) $sql.= " AND s.nom LIKE '%".$db->escape($search_nom)."%'"; if ($search_nom) {
if ($search_contract) $sql.= " AND (".(is_numeric($search_contract)?"c.rowid = ".$db->escape($search_contract)." OR ":'')." c.ref LIKE '%".$db->escape($search_contract)."%')"; $sql .= natural_search(array('s.nom'), $search_nom);
if ($sall) $sql.= " AND (s.nom LIKE '%".$db->escape($sall)."%' OR cd.label LIKE '%".$db->escape($sall)."%' OR cd.description LIKE '%".$db->escape($sall)."%')"; }
if ($search_contract) {
$sql .= natural_search(array('c.rowid', 'c.ref'), $search_contract);
}
if ($sall) {
$sql .= natural_search(array('s.nom', 'cd.label', 'cd.description'), $sall);
}
$sql.= " GROUP BY c.rowid, c.ref, c.datec, c.date_contrat, c.statut,"; $sql.= " GROUP BY c.rowid, c.ref, c.datec, c.date_contrat, c.statut,";
$sql.= " s.nom, s.rowid"; $sql.= " s.nom, s.rowid";
$sql.= " ORDER BY $sortfield $sortorder"; $sql.= " ORDER BY $sortfield $sortorder";

View File

@@ -8,6 +8,7 @@
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2008 Raphael Bertrand (Resultic) <raphael.bertrand@resultic.fr> * Copyright (C) 2008 Raphael Bertrand (Resultic) <raphael.bertrand@resultic.fr>
* Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -4436,4 +4437,35 @@ if (! function_exists('getmypid'))
} }
} }
/**
* Natural search
* @param array[string] $fields array filled with the fields names in the SQL query
* @param string $value the value to look for
* @return string $res the statement to append to the SQL query
* */
function natural_search($fields, $value)
{
global $db;
$crits = explode(' ', $value);
$res = "";
$end = count($fields);
$end2 = count($crits);
$j = 0;
foreach ($crits as $crit) {
$i = 0;
foreach ($fields as $field) {
if ( $i > 0 && $i < $end){
$res .= " OR ";
}
$res .= $field . " LIKE '%" . $db->escape(trim($crit)) . "%'";
$i++;
}
if ($end > 1) $res .= ')';
if ($j < $end2 - 1) $res .= " AND ";
if ($end > 1 && $j < $end2 - 1) $res .= '(';
$j++;
}
return " AND " . ($end > 1? '(' : '') . $res;
}
?> ?>

View File

@@ -3,6 +3,7 @@
* Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2011-2012 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2011-2012 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -73,9 +74,15 @@ $sql.= ", ".MAIN_DB_PREFIX."fichinter as f)";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."fichinterdet as fd ON fd.fk_fichinter = f.rowid"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."fichinterdet as fd ON fd.fk_fichinter = f.rowid";
$sql.= " WHERE f.fk_soc = s.rowid "; $sql.= " WHERE f.fk_soc = s.rowid ";
$sql.= " AND f.entity = ".$conf->entity; $sql.= " AND f.entity = ".$conf->entity;
if ($search_ref) $sql .= " AND f.ref LIKE '%".$db->escape($search_ref)."%'"; if ($search_ref) {
if ($search_company) $sql .= " AND s.nom LIKE '%".$db->escape($search_company)."%'"; $sql .= natural_search(array('f.ref'), $search_ref);
if ($search_desc) $sql .= " AND (f.description LIKE '%".$db->escape($search_desc)."%' OR fd.description LIKE '%".$db->escape($search_desc)."%')"; }
if ($search_company) {
$sql .= natural_search(array('s.nom'), $search_company);
}
if ($search_desc) {
$sql .= natural_search(array('f.description', 'fd.description'), $search_desc);
}
if (! $user->rights->societe->client->voir && empty($socid)) if (! $user->rights->societe->client->voir && empty($socid))
$sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
if ($socid) if ($socid)

View File

@@ -2,6 +2,7 @@
/* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org> /* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -92,11 +93,11 @@ $sql.= " AND cf.entity = ".$conf->entity;
if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
if ($sref) if ($sref)
{ {
$sql.= " AND cf.ref LIKE '%".$db->escape($sref)."%'"; $sql .= natural_search(array('cf.ref'), $sref);
} }
if ($snom) if ($snom)
{ {
$sql.= " AND s.nom LIKE '%".$db->escape($snom)."%'"; $sql .= natural_search(array('s.nom'), $snom);
} }
if ($suser) if ($suser)
{ {
@@ -108,7 +109,7 @@ if ($sttc)
} }
if ($sall) if ($sall)
{ {
$sql.= " AND (cf.ref LIKE '%".$db->escape($sall)."%' OR cf.note LIKE '%".$db->escape($sall)."%')"; $sql .= natural_search(array('cf.ref', 'cf.note_public'), $sall);
} }
if ($socid) $sql.= " AND s.rowid = ".$socid; if ($socid) $sql.= " AND s.rowid = ".$socid;

View File

@@ -4,6 +4,7 @@
* Copyright (C) 2005-2013 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2013 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2013 Philippe Grand <philippe.grand@atoo-net.com> * Copyright (C) 2013 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro> * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -130,12 +131,12 @@ if (GETPOST('filtre'))
if (GETPOST("search_ref")) if (GETPOST("search_ref"))
{ {
if (is_numeric(GETPOST("search_ref"))) $sql .= " AND (fac.rowid = ".GETPOST("search_ref",'int')." OR fac.ref = '".$db->escape(GETPOST("search_ref"))."')"; // For backward compatibility if (is_numeric(GETPOST("search_ref"))) $sql .= natural_search(array('fac.rowid', 'fac.ref'), GETPOST('search_ref'));// For backward compatibility
else $sql .= " AND fac.ref LIKE '%".$db->escape(GETPOST("search_ref"))."%'"; else $sql .= natural_search(array('fac.ref'), GETPOST("search_ref"));
} }
if (GETPOST("search_ref_supplier")) if (GETPOST("search_ref_supplier"))
{ {
$sql .= " AND fac.ref_supplier LIKE '%".$db->escape(GETPOST("search_ref_supplier"))."%'"; $sql .= natural_search(array('fac.ref_supplier'), GETPOST('search_ref_supplier'));
} }
if ($month > 0) if ($month > 0)
{ {
@@ -150,12 +151,12 @@ else if ($year > 0)
} }
if (GETPOST("search_libelle")) if (GETPOST("search_libelle"))
{ {
$sql .= " AND fac.libelle LIKE '%".$db->escape(GETPOST("search_libelle"))."%'"; $sql .= natural_search(array('fac.libelle'), GETPOST('search_libelle'));
} }
if (GETPOST("search_societe")) if (GETPOST("search_societe"))
{ {
$sql .= " AND s.nom LIKE '%".$db->escape(GETPOST("search_societe"))."%'"; $sql .= natural_search(array('s.nom'), GETPOST('search_societe'));
} }
if (GETPOST("search_montant_ht")) if (GETPOST("search_montant_ht"))

View File

@@ -3,6 +3,7 @@
* Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2011 Philippe Grand <philippe.grand@atoo-net.com> * Copyright (C) 2011 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -88,15 +89,18 @@ $sql.= " WHERE s.fk_stcomm = st.id AND s.fournisseur = 1";
$sql.= " AND s.entity IN (".getEntity('societe', 1).")"; $sql.= " AND s.entity IN (".getEntity('societe', 1).")";
if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
if ($socid) $sql .= " AND s.rowid = ".$socid; if ($socid) $sql .= " AND s.rowid = ".$socid;
if ($socname) if ($socname) {
{ $sql .= natural_search(array('s.nom'), $socname);
$sql .= " AND s.nom LIKE '%".$db->escape($socname)."%'";
$sortfield = "s.nom"; $sortfield = "s.nom";
$sortorder = "ASC"; $sortorder = "ASC";
} }
if ($search_nom) $sql .= " AND s.nom LIKE '%".$db->escape($search_nom)."%'"; if ($search_nom) {
$sql .= natural_search(array('s.nom'), $search_nom);
}
if ($search_zipcode) $sql .= " AND s.zip LIKE '".$db->escape($search_zipcode)."%'"; if ($search_zipcode) $sql .= " AND s.zip LIKE '".$db->escape($search_zipcode)."%'";
if ($search_town) $sql .= " AND s.town LIKE '%".$db->escape($search_town)."%'"; if ($search_town) {
$sql .= natural_search(array('s.town'), $search_town);
}
if ($search_code_fournisseur) $sql .= " AND s.code_fournisseur LIKE '%".$db->escape($search_code_fournisseur)."%'"; if ($search_code_fournisseur) $sql .= " AND s.code_fournisseur LIKE '%".$db->escape($search_code_fournisseur)."%'";
if ($search_compta_fournisseur) $sql .= " AND s.code_compta_fournisseur LIKE '%".$db->escape($search_compta_fournisseur)."%'"; if ($search_compta_fournisseur) $sql .= " AND s.code_compta_fournisseur LIKE '%".$db->escape($search_compta_fournisseur)."%'";
if ($search_datec) $sql .= " AND s.datec LIKE '%".$db->escape($search_datec)."%'"; if ($search_datec) $sql .= " AND s.datec LIKE '%".$db->escape($search_datec)."%'";
@@ -229,4 +233,4 @@ else
$db->close(); $db->close();
llxFooter(); llxFooter();
?> ?>

View File

@@ -4,6 +4,7 @@
* Copyright (C) 2005-2007 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2007 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2010 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2010 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr> * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -35,35 +36,32 @@ $langs->load("suppliers");
if (!$user->rights->produit->lire && !$user->rights->service->lire) accessforbidden(); if (!$user->rights->produit->lire && !$user->rights->service->lire) accessforbidden();
$sref=isset($_GET["sref"])?$_GET["sref"]:$_POST["sref"]; $sref = GETPOST('sref');
$sRefSupplier=isset($_GET["srefsupplier"])?$_GET["srefsupplier"]:$_POST["srefsupplier"]; $sRefSupplier = GETPOST('srefsupplier');
$snom=isset($_GET["snom"])?$_GET["snom"]:$_POST["snom"]; $snom = GETPOST('snom');
$type = GETPOST('type');
$type=isset($_GET["type"])?$_GET["type"]:$_POST["type"]; $sortfield = GETPOST('sortfield');
$sortorder = GETPOST('sortorder');
$sortfield = isset($_GET["sortfield"])?$_GET["sortfield"]:$_POST["sortfield"]; $page = GETPOST('page');
$sortorder = isset($_GET["sortorder"])?$_GET["sortorder"]:$_POST["sortorder"];
$page = $_GET["page"];
if ($page < 0) { if ($page < 0) {
$page = 0 ; } $page = 0 ;
}
$limit = $conf->liste_limit; $limit = $conf->liste_limit;
$offset = $limit * $page ; $offset = $limit * $page ;
if (! $sortfield) $sortfield="p.ref"; if (! $sortfield) $sortfield = 'p.ref';
if (! $sortorder) $sortorder="DESC"; if (! $sortorder) $sortorder = 'DESC';
if (! empty($_POST["button_removefilter"])) if (! empty(GETPOST('button_removefilter')))
{ {
$sref=""; $sref = '';
$sRefSupplier=""; $sRefSupplier = '';
$snom=""; $snom = '';
} }
if ($_GET["fourn_id"] > 0 || $_POST["fourn_id"] > 0) $fourn_id = GETPOST('fourn_id', 'int');
{
$fourn_id = isset($_GET["fourn_id"])?$_GET["fourn_id"]:$_POST["fourn_id"];
}
if (isset($_REQUEST['catid'])) if (isset($_REQUEST['catid']))
{ {
@@ -96,38 +94,33 @@ if ($catid) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON cp.f
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as ppf ON p.rowid = ppf.fk_product"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as ppf ON p.rowid = ppf.fk_product";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON ppf.fk_soc = s.rowid"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON ppf.fk_soc = s.rowid";
$sql.= " WHERE p.entity IN (".getEntity('product', 1).")"; $sql.= " WHERE p.entity IN (".getEntity('product', 1).")";
if ($_POST["mode"] == 'search') if (GETPOST('mode', 'alpha') == 'search')
{ {
$sql .= " AND (p.ref LIKE '%".$_POST["sall"]."%'"; $sql .= natural_search(array('p.ref', 'p.label'), GETPOST('mode', 'alpha'));
$sql .= " OR p.label LIKE '%".$_POST["sall"]."%')";
if ($sRefSupplier)
{
$sql .= " AND ppf.ref_fourn LIKE '%".$sRefSupplier."%'";
}
} }
else else
{ {
if ($_GET["type"] || $_POST["type"]) if (GETPOST('type'))
{ {
$sql .= " AND p.fk_product_type = ".(isset($_GET["type"])?$_GET["type"]:$_POST["type"]); $sql .= " AND p.fk_product_type = " . GETPOST('type'));
} }
if ($sref) if ($sref)
{ {
$sql .= " AND p.ref LIKE '%".$sref."%'"; $sql .= natural_search(array('p.ref'), $sref);
}
if ($sRefSupplier)
{
$sql .= " AND ppf.ref_fourn LIKE '%".$sRefSupplier."%'";
} }
if ($snom) if ($snom)
{ {
$sql .= " AND p.label LIKE '%".$snom."%'"; $sql .= natural_search(array('p.label'), $snom);
} }
if($catid) if($catid)
{ {
$sql .= " AND cp.fk_categorie = ".$catid; $sql .= " AND cp.fk_categorie = ".$catid;
} }
} }
if ($sRefSupplier)
{
$sql .= natural_search(array('ppf.ref_fourn'), $sRefSupplier);
}
if ($fourn_id > 0) if ($fourn_id > 0)
{ {
$sql .= " AND ppf.fk_soc = ".$fourn_id; $sql .= " AND ppf.fk_soc = ".$fourn_id;

View File

@@ -1,306 +1,306 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview jQuery adapter provides easy use of basic CKEditor functions * @fileOverview jQuery adapter provides easy use of basic CKEditor functions
* and access to internal API. It also integrates some aspects of CKEditor with * and access to internal API. It also integrates some aspects of CKEditor with
* jQuery framework. * jQuery framework.
* *
* Every TEXTAREA, DIV and P elements can be converted to working editor. * Every TEXTAREA, DIV and P elements can be converted to working editor.
* *
* Plugin exposes some of editor's event to jQuery event system. All of those are namespaces inside * Plugin exposes some of editor's event to jQuery event system. All of those are namespaces inside
* ".ckeditor" namespace and can be binded/listened on supported textarea, div and p nodes. * ".ckeditor" namespace and can be binded/listened on supported textarea, div and p nodes.
* *
* Available jQuery events: * Available jQuery events:
* - instanceReady.ckeditor( editor, rootNode ) * - instanceReady.ckeditor( editor, rootNode )
* Triggered when new instance is ready. * Triggered when new instance is ready.
* - destroy.ckeditor( editor ) * - destroy.ckeditor( editor )
* Triggered when instance is destroyed. * Triggered when instance is destroyed.
* - getData.ckeditor( editor, eventData ) * - getData.ckeditor( editor, eventData )
* Triggered when getData event is fired inside editor. It can change returned data using eventData reference. * Triggered when getData event is fired inside editor. It can change returned data using eventData reference.
* - setData.ckeditor( editor ) * - setData.ckeditor( editor )
* Triggered when getData event is fired inside editor. * Triggered when getData event is fired inside editor.
* *
* @example * @example
* <script src="jquery.js"></script> * <script src="jquery.js"></script>
* <script src="ckeditor.js"></script> * <script src="ckeditor.js"></script>
* <script src="adapters/jquery/adapter.js"></script> * <script src="adapters/jquery/adapter.js"></script>
*/ */
(function() (function()
{ {
/** /**
* Allows CKEditor to override jQuery.fn.val(), making it possible to use the val() * Allows CKEditor to override jQuery.fn.val(), making it possible to use the val()
* function on textareas, as usual, having it synchronized with CKEditor.<br> * function on textareas, as usual, having it synchronized with CKEditor.<br>
* <br> * <br>
* This configuration option is global and executed during the jQuery Adapter loading. * This configuration option is global and executed during the jQuery Adapter loading.
* It can't be customized across editor instances. * It can't be customized across editor instances.
* @type Boolean * @type Boolean
* @example * @example
* &lt;script&gt; * &lt;script&gt;
* CKEDITOR.config.jqueryOverrideVal = true; * CKEDITOR.config.jqueryOverrideVal = true;
* &lt;/script&gt; * &lt;/script&gt;
* &lt;!-- Important: The JQuery adapter is loaded *after* setting jqueryOverrideVal --&gt; * &lt;!-- Important: The JQuery adapter is loaded *after* setting jqueryOverrideVal --&gt;
* &lt;script src="/ckeditor/adapters/jquery.js"&gt;&lt;/script&gt; * &lt;script src="/ckeditor/adapters/jquery.js"&gt;&lt;/script&gt;
* @example * @example
* // ... then later in the code ... * // ... then later in the code ...
* *
* $( 'textarea' ).ckeditor(); * $( 'textarea' ).ckeditor();
* // ... * // ...
* $( 'textarea' ).val( 'New content' ); * $( 'textarea' ).val( 'New content' );
*/ */
CKEDITOR.config.jqueryOverrideVal = typeof CKEDITOR.config.jqueryOverrideVal == 'undefined' CKEDITOR.config.jqueryOverrideVal = typeof CKEDITOR.config.jqueryOverrideVal == 'undefined'
? true : CKEDITOR.config.jqueryOverrideVal; ? true : CKEDITOR.config.jqueryOverrideVal;
var jQuery = window.jQuery; var jQuery = window.jQuery;
if ( typeof jQuery == 'undefined' ) if ( typeof jQuery == 'undefined' )
return; return;
// jQuery object methods. // jQuery object methods.
jQuery.extend( jQuery.fn, jQuery.extend( jQuery.fn,
/** @lends jQuery.fn */ /** @lends jQuery.fn */
{ {
/** /**
* Return existing CKEditor instance for first matched element. * Return existing CKEditor instance for first matched element.
* Allows to easily use internal API. Doesn't return jQuery object. * Allows to easily use internal API. Doesn't return jQuery object.
* *
* Raised exception if editor doesn't exist or isn't ready yet. * Raised exception if editor doesn't exist or isn't ready yet.
* *
* @name jQuery.ckeditorGet * @name jQuery.ckeditorGet
* @return CKEDITOR.editor * @return CKEDITOR.editor
* @see CKEDITOR.editor * @see CKEDITOR.editor
*/ */
ckeditorGet: function() ckeditorGet: function()
{ {
var instance = this.eq( 0 ).data( 'ckeditorInstance' ); var instance = this.eq( 0 ).data( 'ckeditorInstance' );
if ( !instance ) if ( !instance )
throw "CKEditor not yet initialized, use ckeditor() with callback."; throw "CKEditor not yet initialized, use ckeditor() with callback.";
return instance; return instance;
}, },
/** /**
* Triggers creation of CKEditor in all matched elements (reduced to DIV, P and TEXTAREAs). * Triggers creation of CKEditor in all matched elements (reduced to DIV, P and TEXTAREAs).
* Binds callback to instanceReady event of all instances. If editor is already created, than * Binds callback to instanceReady event of all instances. If editor is already created, than
* callback is fired right away. * callback is fired right away.
* *
* Mixed parameter order allowed. * Mixed parameter order allowed.
* *
* @param callback Function to be run on editor instance. Passed parameters: [ textarea ]. * @param callback Function to be run on editor instance. Passed parameters: [ textarea ].
* Callback is fiered in "this" scope being ckeditor instance and having source textarea as first param. * Callback is fiered in "this" scope being ckeditor instance and having source textarea as first param.
* *
* @param config Configuration options for new instance(s) if not already created. * @param config Configuration options for new instance(s) if not already created.
* See URL * See URL
* *
* @example * @example
* $( 'textarea' ).ckeditor( function( textarea ) { * $( 'textarea' ).ckeditor( function( textarea ) {
* $( textarea ).val( this.getData() ) * $( textarea ).val( this.getData() )
* } ); * } );
* *
* @name jQuery.fn.ckeditor * @name jQuery.fn.ckeditor
* @return jQuery.fn * @return jQuery.fn
*/ */
ckeditor: function( callback, config ) ckeditor: function( callback, config )
{ {
if ( !CKEDITOR.env.isCompatible ) if ( !CKEDITOR.env.isCompatible )
return this; return this;
if ( !jQuery.isFunction( callback )) if ( !jQuery.isFunction( callback ))
{ {
var tmp = config; var tmp = config;
config = callback; config = callback;
callback = tmp; callback = tmp;
} }
config = config || {}; config = config || {};
this.filter( 'textarea, div, p' ).each( function() this.filter( 'textarea, div, p' ).each( function()
{ {
var $element = jQuery( this ), var $element = jQuery( this ),
editor = $element.data( 'ckeditorInstance' ), editor = $element.data( 'ckeditorInstance' ),
instanceLock = $element.data( '_ckeditorInstanceLock' ), instanceLock = $element.data( '_ckeditorInstanceLock' ),
element = this; element = this;
if ( editor && !instanceLock ) if ( editor && !instanceLock )
{ {
if ( callback ) if ( callback )
callback.apply( editor, [ this ] ); callback.apply( editor, [ this ] );
} }
else if ( !instanceLock ) else if ( !instanceLock )
{ {
// CREATE NEW INSTANCE // CREATE NEW INSTANCE
// Handle config.autoUpdateElement inside this plugin if desired. // Handle config.autoUpdateElement inside this plugin if desired.
if ( config.autoUpdateElement if ( config.autoUpdateElement
|| ( typeof config.autoUpdateElement == 'undefined' && CKEDITOR.config.autoUpdateElement ) ) || ( typeof config.autoUpdateElement == 'undefined' && CKEDITOR.config.autoUpdateElement ) )
{ {
config.autoUpdateElementJquery = true; config.autoUpdateElementJquery = true;
} }
// Always disable config.autoUpdateElement. // Always disable config.autoUpdateElement.
config.autoUpdateElement = false; config.autoUpdateElement = false;
$element.data( '_ckeditorInstanceLock', true ); $element.data( '_ckeditorInstanceLock', true );
// Set instance reference in element's data. // Set instance reference in element's data.
editor = CKEDITOR.replace( element, config ); editor = CKEDITOR.replace( element, config );
$element.data( 'ckeditorInstance', editor ); $element.data( 'ckeditorInstance', editor );
// Register callback. // Register callback.
editor.on( 'instanceReady', function( event ) editor.on( 'instanceReady', function( event )
{ {
var editor = event.editor; var editor = event.editor;
setTimeout( function() setTimeout( function()
{ {
// Delay bit more if editor is still not ready. // Delay bit more if editor is still not ready.
if ( !editor.element ) if ( !editor.element )
{ {
setTimeout( arguments.callee, 100 ); setTimeout( arguments.callee, 100 );
return; return;
} }
// Remove this listener. // Remove this listener.
event.removeListener( 'instanceReady', this.callee ); event.removeListener( 'instanceReady', this.callee );
// Forward setData on dataReady. // Forward setData on dataReady.
editor.on( 'dataReady', function() editor.on( 'dataReady', function()
{ {
$element.trigger( 'setData' + '.ckeditor', [ editor ] ); $element.trigger( 'setData' + '.ckeditor', [ editor ] );
}); });
// Forward getData. // Forward getData.
editor.on( 'getData', function( event ) { editor.on( 'getData', function( event ) {
$element.trigger( 'getData' + '.ckeditor', [ editor, event.data ] ); $element.trigger( 'getData' + '.ckeditor', [ editor, event.data ] );
}, 999 ); }, 999 );
// Forward destroy event. // Forward destroy event.
editor.on( 'destroy', function() editor.on( 'destroy', function()
{ {
$element.trigger( 'destroy.ckeditor', [ editor ] ); $element.trigger( 'destroy.ckeditor', [ editor ] );
}); });
// Integrate with form submit. // Integrate with form submit.
if ( editor.config.autoUpdateElementJquery && $element.is( 'textarea' ) && $element.parents( 'form' ).length ) if ( editor.config.autoUpdateElementJquery && $element.is( 'textarea' ) && $element.parents( 'form' ).length )
{ {
var onSubmit = function() var onSubmit = function()
{ {
$element.ckeditor( function() $element.ckeditor( function()
{ {
editor.updateElement(); editor.updateElement();
}); });
}; };
// Bind to submit event. // Bind to submit event.
$element.parents( 'form' ).submit( onSubmit ); $element.parents( 'form' ).submit( onSubmit );
// Bind to form-pre-serialize from jQuery Forms plugin. // Bind to form-pre-serialize from jQuery Forms plugin.
$element.parents( 'form' ).bind( 'form-pre-serialize', onSubmit ); $element.parents( 'form' ).bind( 'form-pre-serialize', onSubmit );
// Unbind when editor destroyed. // Unbind when editor destroyed.
$element.bind( 'destroy.ckeditor', function() $element.bind( 'destroy.ckeditor', function()
{ {
$element.parents( 'form' ).unbind( 'submit', onSubmit ); $element.parents( 'form' ).unbind( 'submit', onSubmit );
$element.parents( 'form' ).unbind( 'form-pre-serialize', onSubmit ); $element.parents( 'form' ).unbind( 'form-pre-serialize', onSubmit );
}); });
} }
// Garbage collect on destroy. // Garbage collect on destroy.
editor.on( 'destroy', function() editor.on( 'destroy', function()
{ {
$element.data( 'ckeditorInstance', null ); $element.data( 'ckeditorInstance', null );
}); });
// Remove lock. // Remove lock.
$element.data( '_ckeditorInstanceLock', null ); $element.data( '_ckeditorInstanceLock', null );
// Fire instanceReady event. // Fire instanceReady event.
$element.trigger( 'instanceReady.ckeditor', [ editor ] ); $element.trigger( 'instanceReady.ckeditor', [ editor ] );
// Run given (first) code. // Run given (first) code.
if ( callback ) if ( callback )
callback.apply( editor, [ element ] ); callback.apply( editor, [ element ] );
}, 0 ); }, 0 );
}, null, null, 9999); }, null, null, 9999);
} }
else else
{ {
// Editor is already during creation process, bind our code to the event. // Editor is already during creation process, bind our code to the event.
CKEDITOR.on( 'instanceReady', function( event ) CKEDITOR.on( 'instanceReady', function( event )
{ {
var editor = event.editor; var editor = event.editor;
setTimeout( function() setTimeout( function()
{ {
// Delay bit more if editor is still not ready. // Delay bit more if editor is still not ready.
if ( !editor.element ) if ( !editor.element )
{ {
setTimeout( arguments.callee, 100 ); setTimeout( arguments.callee, 100 );
return; return;
} }
if ( editor.element.$ == element ) if ( editor.element.$ == element )
{ {
// Run given code. // Run given code.
if ( callback ) if ( callback )
callback.apply( editor, [ element ] ); callback.apply( editor, [ element ] );
} }
}, 0 ); }, 0 );
}, null, null, 9999); }, null, null, 9999);
} }
}); });
return this; return this;
} }
}); });
// New val() method for objects. // New val() method for objects.
if ( CKEDITOR.config.jqueryOverrideVal ) if ( CKEDITOR.config.jqueryOverrideVal )
{ {
jQuery.fn.val = CKEDITOR.tools.override( jQuery.fn.val, function( oldValMethod ) jQuery.fn.val = CKEDITOR.tools.override( jQuery.fn.val, function( oldValMethod )
{ {
/** /**
* CKEditor-aware val() method. * CKEditor-aware val() method.
* *
* Acts same as original jQuery val(), but for textareas which have CKEditor instances binded to them, method * Acts same as original jQuery val(), but for textareas which have CKEditor instances binded to them, method
* returns editor's content. It also works for settings values. * returns editor's content. It also works for settings values.
* *
* @param oldValMethod * @param oldValMethod
* @name jQuery.fn.val * @name jQuery.fn.val
*/ */
return function( newValue, forceNative ) return function( newValue, forceNative )
{ {
var isSetter = typeof newValue != 'undefined', var isSetter = typeof newValue != 'undefined',
result; result;
this.each( function() this.each( function()
{ {
var $this = jQuery( this ), var $this = jQuery( this ),
editor = $this.data( 'ckeditorInstance' ); editor = $this.data( 'ckeditorInstance' );
if ( !forceNative && $this.is( 'textarea' ) && editor ) if ( !forceNative && $this.is( 'textarea' ) && editor )
{ {
if ( isSetter ) if ( isSetter )
editor.setData( newValue ); editor.setData( newValue );
else else
{ {
result = editor.getData(); result = editor.getData();
// break; // break;
return null; return null;
} }
} }
else else
{ {
if ( isSetter ) if ( isSetter )
oldValMethod.call( $this, newValue ); oldValMethod.call( $this, newValue );
else else
{ {
result = oldValMethod.call( $this ); result = oldValMethod.call( $this );
// break; // break;
return null; return null;
} }
} }
return true; return true;
}); });
return isSetter ? this : result; return isSetter ? this : result;
}; };
}); });
} }
})(); })();

View File

@@ -1,87 +1,87 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview API initialization code. * @fileOverview API initialization code.
*/ */
(function() (function()
{ {
// Disable HC detaction in WebKit. (#5429) // Disable HC detaction in WebKit. (#5429)
if ( CKEDITOR.env.webkit ) if ( CKEDITOR.env.webkit )
{ {
CKEDITOR.env.hc = false; CKEDITOR.env.hc = false;
return; return;
} }
// Check whether high contrast is active by creating a colored border. // Check whether high contrast is active by creating a colored border.
var hcDetect = CKEDITOR.dom.element.createFromHtml( var hcDetect = CKEDITOR.dom.element.createFromHtml(
'<div style="width:0px;height:0px;position:absolute;left:-10000px;' + '<div style="width:0px;height:0px;position:absolute;left:-10000px;' +
'border: 1px solid;border-color: red blue;"></div>', CKEDITOR.document ); 'border: 1px solid;border-color: red blue;"></div>', CKEDITOR.document );
hcDetect.appendTo( CKEDITOR.document.getHead() ); hcDetect.appendTo( CKEDITOR.document.getHead() );
// Update CKEDITOR.env. // Update CKEDITOR.env.
// Catch exception needed sometimes for FF. (#4230) // Catch exception needed sometimes for FF. (#4230)
try try
{ {
CKEDITOR.env.hc = hcDetect.getComputedStyle( 'border-top-color' ) == hcDetect.getComputedStyle( 'border-right-color' ); CKEDITOR.env.hc = hcDetect.getComputedStyle( 'border-top-color' ) == hcDetect.getComputedStyle( 'border-right-color' );
} }
catch (e) catch (e)
{ {
CKEDITOR.env.hc = false; CKEDITOR.env.hc = false;
} }
if ( CKEDITOR.env.hc ) if ( CKEDITOR.env.hc )
CKEDITOR.env.cssClass += ' cke_hc'; CKEDITOR.env.cssClass += ' cke_hc';
hcDetect.remove(); hcDetect.remove();
})(); })();
// Load core plugins. // Load core plugins.
CKEDITOR.plugins.load( CKEDITOR.config.corePlugins.split( ',' ), function() CKEDITOR.plugins.load( CKEDITOR.config.corePlugins.split( ',' ), function()
{ {
CKEDITOR.status = 'loaded'; CKEDITOR.status = 'loaded';
CKEDITOR.fire( 'loaded' ); CKEDITOR.fire( 'loaded' );
// Process all instances created by the "basic" implementation. // Process all instances created by the "basic" implementation.
var pending = CKEDITOR._.pending; var pending = CKEDITOR._.pending;
if ( pending ) if ( pending )
{ {
delete CKEDITOR._.pending; delete CKEDITOR._.pending;
for ( var i = 0 ; i < pending.length ; i++ ) for ( var i = 0 ; i < pending.length ; i++ )
CKEDITOR.add( pending[ i ] ); CKEDITOR.add( pending[ i ] );
} }
}); });
// Needed for IE6 to not request image (HTTP 200 or 304) for every CSS background. (#6187) // Needed for IE6 to not request image (HTTP 200 or 304) for every CSS background. (#6187)
if ( CKEDITOR.env.ie ) if ( CKEDITOR.env.ie )
{ {
// Remove IE mouse flickering on IE6 because of background images. // Remove IE mouse flickering on IE6 because of background images.
try try
{ {
document.execCommand( 'BackgroundImageCache', false, true ); document.execCommand( 'BackgroundImageCache', false, true );
} }
catch (e) catch (e)
{ {
// We have been reported about loading problems caused by the above // We have been reported about loading problems caused by the above
// line. For safety, let's just ignore errors. // line. For safety, let's just ignore errors.
} }
} }
/** /**
* Indicates that CKEditor is running on a High Contrast environment. * Indicates that CKEditor is running on a High Contrast environment.
* @name CKEDITOR.env.hc * @name CKEDITOR.env.hc
* @example * @example
* if ( CKEDITOR.env.hc ) * if ( CKEDITOR.env.hc )
* alert( 'You're running on High Contrast mode. The editor interface will get adapted to provide you a better experience.' ); * alert( 'You're running on High Contrast mode. The editor interface will get adapted to provide you a better experience.' );
*/ */
/** /**
* Fired when a CKEDITOR core object is fully loaded and ready for interaction. * Fired when a CKEDITOR core object is fully loaded and ready for interaction.
* @name CKEDITOR#loaded * @name CKEDITOR#loaded
* @event * @event
*/ */

View File

@@ -1,141 +1,141 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Contains the third and last part of the {@link CKEDITOR} object * @fileOverview Contains the third and last part of the {@link CKEDITOR} object
* definition. * definition.
*/ */
// Remove the CKEDITOR.loadFullCore reference defined on ckeditor_basic. // Remove the CKEDITOR.loadFullCore reference defined on ckeditor_basic.
delete CKEDITOR.loadFullCore; delete CKEDITOR.loadFullCore;
/** /**
* Holds references to all editor instances created. The name of the properties * Holds references to all editor instances created. The name of the properties
* in this object correspond to instance names, and their values contains the * in this object correspond to instance names, and their values contains the
* {@link CKEDITOR.editor} object representing them. * {@link CKEDITOR.editor} object representing them.
* @type {Object} * @type {Object}
* @example * @example
* alert( <b>CKEDITOR.instances</b>.editor1.name ); // "editor1" * alert( <b>CKEDITOR.instances</b>.editor1.name ); // "editor1"
*/ */
CKEDITOR.instances = {}; CKEDITOR.instances = {};
/** /**
* The document of the window holding the CKEDITOR object. * The document of the window holding the CKEDITOR object.
* @type {CKEDITOR.dom.document} * @type {CKEDITOR.dom.document}
* @example * @example
* alert( <b>CKEDITOR.document</b>.getBody().getName() ); // "body" * alert( <b>CKEDITOR.document</b>.getBody().getName() ); // "body"
*/ */
CKEDITOR.document = new CKEDITOR.dom.document( document ); CKEDITOR.document = new CKEDITOR.dom.document( document );
/** /**
* Adds an editor instance to the global {@link CKEDITOR} object. This function * Adds an editor instance to the global {@link CKEDITOR} object. This function
* is available for internal use mainly. * is available for internal use mainly.
* @param {CKEDITOR.editor} editor The editor instance to be added. * @param {CKEDITOR.editor} editor The editor instance to be added.
* @example * @example
*/ */
CKEDITOR.add = function( editor ) CKEDITOR.add = function( editor )
{ {
CKEDITOR.instances[ editor.name ] = editor; CKEDITOR.instances[ editor.name ] = editor;
editor.on( 'focus', function() editor.on( 'focus', function()
{ {
if ( CKEDITOR.currentInstance != editor ) if ( CKEDITOR.currentInstance != editor )
{ {
CKEDITOR.currentInstance = editor; CKEDITOR.currentInstance = editor;
CKEDITOR.fire( 'currentInstance' ); CKEDITOR.fire( 'currentInstance' );
} }
}); });
editor.on( 'blur', function() editor.on( 'blur', function()
{ {
if ( CKEDITOR.currentInstance == editor ) if ( CKEDITOR.currentInstance == editor )
{ {
CKEDITOR.currentInstance = null; CKEDITOR.currentInstance = null;
CKEDITOR.fire( 'currentInstance' ); CKEDITOR.fire( 'currentInstance' );
} }
}); });
}; };
/** /**
* Removes an editor instance from the global {@link CKEDITOR} object. This function * Removes an editor instance from the global {@link CKEDITOR} object. This function
* is available for internal use only. External code must use {@link CKEDITOR.editor.prototype.destroy} * is available for internal use only. External code must use {@link CKEDITOR.editor.prototype.destroy}
* to avoid memory leaks. * to avoid memory leaks.
* @param {CKEDITOR.editor} editor The editor instance to be removed. * @param {CKEDITOR.editor} editor The editor instance to be removed.
* @example * @example
*/ */
CKEDITOR.remove = function( editor ) CKEDITOR.remove = function( editor )
{ {
delete CKEDITOR.instances[ editor.name ]; delete CKEDITOR.instances[ editor.name ];
}; };
/** /**
* Perform global clean up to free as much memory as possible * Perform global clean up to free as much memory as possible
* when there are no instances left * when there are no instances left
*/ */
CKEDITOR.on( 'instanceDestroyed', function () CKEDITOR.on( 'instanceDestroyed', function ()
{ {
if ( CKEDITOR.tools.isEmpty( this.instances ) ) if ( CKEDITOR.tools.isEmpty( this.instances ) )
CKEDITOR.fire( 'reset' ); CKEDITOR.fire( 'reset' );
}); });
// Load the bootstrap script. // Load the bootstrap script.
CKEDITOR.loader.load( 'core/_bootstrap' ); // @Packager.RemoveLine CKEDITOR.loader.load( 'core/_bootstrap' ); // @Packager.RemoveLine
// Tri-state constants. // Tri-state constants.
/** /**
* Used to indicate the ON or ACTIVE state. * Used to indicate the ON or ACTIVE state.
* @constant * @constant
* @example * @example
*/ */
CKEDITOR.TRISTATE_ON = 1; CKEDITOR.TRISTATE_ON = 1;
/** /**
* Used to indicate the OFF or NON ACTIVE state. * Used to indicate the OFF or NON ACTIVE state.
* @constant * @constant
* @example * @example
*/ */
CKEDITOR.TRISTATE_OFF = 2; CKEDITOR.TRISTATE_OFF = 2;
/** /**
* Used to indicate DISABLED state. * Used to indicate DISABLED state.
* @constant * @constant
* @example * @example
*/ */
CKEDITOR.TRISTATE_DISABLED = 0; CKEDITOR.TRISTATE_DISABLED = 0;
/** /**
* The editor which is currently active (have user focus). * The editor which is currently active (have user focus).
* @name CKEDITOR.currentInstance * @name CKEDITOR.currentInstance
* @type CKEDITOR.editor * @type CKEDITOR.editor
* @see CKEDITOR#currentInstance * @see CKEDITOR#currentInstance
* @example * @example
* function showCurrentEditorName() * function showCurrentEditorName()
* { * {
* if ( CKEDITOR.currentInstance ) * if ( CKEDITOR.currentInstance )
* alert( CKEDITOR.currentInstance.name ); * alert( CKEDITOR.currentInstance.name );
* else * else
* alert( 'Please focus an editor first.' ); * alert( 'Please focus an editor first.' );
* } * }
*/ */
/** /**
* Fired when the CKEDITOR.currentInstance object reference changes. This may * Fired when the CKEDITOR.currentInstance object reference changes. This may
* happen when setting the focus on different editor instances in the page. * happen when setting the focus on different editor instances in the page.
* @name CKEDITOR#currentInstance * @name CKEDITOR#currentInstance
* @event * @event
* var editor; // Variable to hold a reference to the current editor. * var editor; // Variable to hold a reference to the current editor.
* CKEDITOR.on( 'currentInstance' , function( e ) * CKEDITOR.on( 'currentInstance' , function( e )
* { * {
* editor = CKEDITOR.currentInstance; * editor = CKEDITOR.currentInstance;
* }); * });
*/ */
/** /**
* Fired when the last instance has been destroyed. This event is used to perform * Fired when the last instance has been destroyed. This event is used to perform
* global memory clean up. * global memory clean up.
* @name CKEDITOR#reset * @name CKEDITOR#reset
* @event * @event
*/ */

View File

@@ -1,235 +1,235 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Contains the first and essential part of the {@link CKEDITOR} * @fileOverview Contains the first and essential part of the {@link CKEDITOR}
* object definition. * object definition.
*/ */
// #### Compressed Code // #### Compressed Code
// Must be updated on changes in the script as well as updated in the // Must be updated on changes in the script as well as updated in the
// ckeditor_source.js and ckeditor_basic_source.js files. // ckeditor_source.js and ckeditor_basic_source.js files.
// if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'3.6.4',revision:'7575',rnd:Math.floor(Math.random()*900)+100,_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f<e.length;f++){var g=e[f].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(g){d=g[1];break;}}}if(d.indexOf(':/')==-1)if(d.indexOf('/')===0)d=location.href.match(/^.*?:\/\/[^\/]*/)[0]+d;else d=location.href.match(/^[^\?]*\/(?:)/)[0]+d;if(!d)throw 'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';return d;})(),getUrl:function(d){if(d.indexOf(':/')==-1&&d.indexOf('/')!==0)d=this.basePath+d;if(this.timestamp&&d.charAt(d.length-1)!='/'&&!/[&?]t=/.test(d))d+=(d.indexOf('?')>=0?'&':'?')+'t='+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})(); // if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'3.6.4',revision:'7575',rnd:Math.floor(Math.random()*900)+100,_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f<e.length;f++){var g=e[f].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(g){d=g[1];break;}}}if(d.indexOf(':/')==-1)if(d.indexOf('/')===0)d=location.href.match(/^.*?:\/\/[^\/]*/)[0]+d;else d=location.href.match(/^[^\?]*\/(?:)/)[0]+d;if(!d)throw 'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';return d;})(),getUrl:function(d){if(d.indexOf(':/')==-1&&d.indexOf('/')!==0)d=this.basePath+d;if(this.timestamp&&d.charAt(d.length-1)!='/'&&!/[&?]t=/.test(d))d+=(d.indexOf('?')>=0?'&':'?')+'t='+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})();
// #### Raw code // #### Raw code
// ATTENTION: read the above "Compressed Code" notes when changing this code. // ATTENTION: read the above "Compressed Code" notes when changing this code.
/* @Packager.RemoveLine /* @Packager.RemoveLine
// Avoid having the editor code initialized twice. (#7588) // Avoid having the editor code initialized twice. (#7588)
// Use CKEDITOR.dom to check whether the full ckeditor.js code has been loaded // Use CKEDITOR.dom to check whether the full ckeditor.js code has been loaded
// or just ckeditor_basic.js. // or just ckeditor_basic.js.
// Remove these lines when compressing manually. // Remove these lines when compressing manually.
if ( window.CKEDITOR && window.CKEDITOR.dom ) if ( window.CKEDITOR && window.CKEDITOR.dom )
return; return;
@Packager.RemoveLine */ @Packager.RemoveLine */
if ( !window.CKEDITOR ) if ( !window.CKEDITOR )
{ {
/** /**
* @name CKEDITOR * @name CKEDITOR
* @namespace This is the API entry point. The entire CKEditor code runs under this object. * @namespace This is the API entry point. The entire CKEditor code runs under this object.
* @example * @example
*/ */
window.CKEDITOR = (function() window.CKEDITOR = (function()
{ {
var CKEDITOR = var CKEDITOR =
/** @lends CKEDITOR */ /** @lends CKEDITOR */
{ {
/** /**
* A constant string unique for each release of CKEditor. Its value * A constant string unique for each release of CKEditor. Its value
* is used, by default, to build the URL for all resources loaded * is used, by default, to build the URL for all resources loaded
* by the editor code, guaranteeing clean cache results when * by the editor code, guaranteeing clean cache results when
* upgrading. * upgrading.
* @type String * @type String
* @example * @example
* alert( CKEDITOR.timestamp ); // e.g. '87dm' * alert( CKEDITOR.timestamp ); // e.g. '87dm'
*/ */
// The production implementation contains a fixed timestamp, unique // The production implementation contains a fixed timestamp, unique
// for each release and generated by the releaser. // for each release and generated by the releaser.
// (Base 36 value of each component of YYMMDDHH - 4 chars total - e.g. 87bm == 08071122) // (Base 36 value of each component of YYMMDDHH - 4 chars total - e.g. 87bm == 08071122)
timestamp : 'C6HH5UF', timestamp : 'C6HH5UF',
/** /**
* Contains the CKEditor version number. * Contains the CKEditor version number.
* @type String * @type String
* @example * @example
* alert( CKEDITOR.version ); // e.g. 'CKEditor 3.4.1' * alert( CKEDITOR.version ); // e.g. 'CKEditor 3.4.1'
*/ */
version : '3.6.4', version : '3.6.4',
/** /**
* Contains the CKEditor revision number. * Contains the CKEditor revision number.
* The revision number is incremented automatically, following each * The revision number is incremented automatically, following each
* modification to the CKEditor source code. * modification to the CKEditor source code.
* @type String * @type String
* @example * @example
* alert( CKEDITOR.revision ); // e.g. '3975' * alert( CKEDITOR.revision ); // e.g. '3975'
*/ */
revision : '7575', revision : '7575',
/** /**
* A 3-digit random integer, valid for the entire life of the CKEDITOR object. * A 3-digit random integer, valid for the entire life of the CKEDITOR object.
* @type Number * @type Number
* @example * @example
* alert( CKEDITOR.rnd ); // e.g. '319' * alert( CKEDITOR.rnd ); // e.g. '319'
*/ */
rnd : Math.floor( Math.random() * ( 999/*Max*/ - 100/*Min*/ + 1 ) ) + 100/*Min*/, rnd : Math.floor( Math.random() * ( 999/*Max*/ - 100/*Min*/ + 1 ) ) + 100/*Min*/,
/** /**
* Private object used to hold core stuff. It should not be used outside of * Private object used to hold core stuff. It should not be used outside of
* the API code as properties defined here may change at any time * the API code as properties defined here may change at any time
* without notice. * without notice.
* @private * @private
*/ */
_ : {}, _ : {},
/** /**
* Indicates the API loading status. The following statuses are available: * Indicates the API loading status. The following statuses are available:
* <ul> * <ul>
* <li><b>unloaded</b>: the API is not yet loaded.</li> * <li><b>unloaded</b>: the API is not yet loaded.</li>
* <li><b>basic_loaded</b>: the basic API features are available.</li> * <li><b>basic_loaded</b>: the basic API features are available.</li>
* <li><b>basic_ready</b>: the basic API is ready to load the full core code.</li> * <li><b>basic_ready</b>: the basic API is ready to load the full core code.</li>
* <li><b>loading</b>: the full API is being loaded.</li> * <li><b>loading</b>: the full API is being loaded.</li>
* <li><b>loaded</b>: the API can be fully used.</li> * <li><b>loaded</b>: the API can be fully used.</li>
* </ul> * </ul>
* @type String * @type String
* @example * @example
* if ( <b>CKEDITOR.status</b> == 'loaded' ) * if ( <b>CKEDITOR.status</b> == 'loaded' )
* { * {
* // The API can now be fully used. * // The API can now be fully used.
* } * }
*/ */
status : 'unloaded', status : 'unloaded',
/** /**
* Contains the full URL for the CKEditor installation directory. * Contains the full URL for the CKEditor installation directory.
* It is possible to manually provide the base path by setting a * It is possible to manually provide the base path by setting a
* global variable named CKEDITOR_BASEPATH. This global variable * global variable named CKEDITOR_BASEPATH. This global variable
* must be set <strong>before</strong> the editor script loading. * must be set <strong>before</strong> the editor script loading.
* @type String * @type String
* @example * @example
* alert( <b>CKEDITOR.basePath</b> ); // "http://www.example.com/ckeditor/" (e.g.) * alert( <b>CKEDITOR.basePath</b> ); // "http://www.example.com/ckeditor/" (e.g.)
*/ */
basePath : (function() basePath : (function()
{ {
// ATTENTION: fixes to this code must be ported to // ATTENTION: fixes to this code must be ported to
// var basePath in "core/loader.js". // var basePath in "core/loader.js".
// Find out the editor directory path, based on its <script> tag. // Find out the editor directory path, based on its <script> tag.
var path = window.CKEDITOR_BASEPATH || ''; var path = window.CKEDITOR_BASEPATH || '';
if ( !path ) if ( !path )
{ {
var scripts = document.getElementsByTagName( 'script' ); var scripts = document.getElementsByTagName( 'script' );
for ( var i = 0 ; i < scripts.length ; i++ ) for ( var i = 0 ; i < scripts.length ; i++ )
{ {
var match = scripts[i].src.match( /(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i ); var match = scripts[i].src.match( /(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i );
if ( match ) if ( match )
{ {
path = match[1]; path = match[1];
break; break;
} }
} }
} }
// In IE (only) the script.src string is the raw value entered in the // In IE (only) the script.src string is the raw value entered in the
// HTML source. Other browsers return the full resolved URL instead. // HTML source. Other browsers return the full resolved URL instead.
if ( path.indexOf(':/') == -1 ) if ( path.indexOf(':/') == -1 )
{ {
// Absolute path. // Absolute path.
if ( path.indexOf( '/' ) === 0 ) if ( path.indexOf( '/' ) === 0 )
path = location.href.match( /^.*?:\/\/[^\/]*/ )[0] + path; path = location.href.match( /^.*?:\/\/[^\/]*/ )[0] + path;
// Relative path. // Relative path.
else else
path = location.href.match( /^[^\?]*\/(?:)/ )[0] + path; path = location.href.match( /^[^\?]*\/(?:)/ )[0] + path;
} }
if ( !path ) if ( !path )
throw 'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.'; throw 'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';
return path; return path;
})(), })(),
/** /**
* Gets the full URL for CKEditor resources. By default, URLs * Gets the full URL for CKEditor resources. By default, URLs
* returned by this function contain a querystring parameter ("t") * returned by this function contain a querystring parameter ("t")
* set to the {@link CKEDITOR.timestamp} value.<br /> * set to the {@link CKEDITOR.timestamp} value.<br />
* <br /> * <br />
* It is possible to provide a custom implementation of this * It is possible to provide a custom implementation of this
* function by setting a global variable named CKEDITOR_GETURL. * function by setting a global variable named CKEDITOR_GETURL.
* This global variable must be set <strong>before</strong> the editor script * This global variable must be set <strong>before</strong> the editor script
* loading. If the custom implementation returns nothing (==null), the * loading. If the custom implementation returns nothing (==null), the
* default implementation is used. * default implementation is used.
* @param {String} resource The resource whose full URL we want to get. * @param {String} resource The resource whose full URL we want to get.
* It may be a full, absolute, or relative URL. * It may be a full, absolute, or relative URL.
* @returns {String} The full URL. * @returns {String} The full URL.
* @example * @example
* // e.g. http://www.example.com/ckeditor/skins/default/editor.css?t=87dm * // e.g. http://www.example.com/ckeditor/skins/default/editor.css?t=87dm
* alert( CKEDITOR.getUrl( 'skins/default/editor.css' ) ); * alert( CKEDITOR.getUrl( 'skins/default/editor.css' ) );
* @example * @example
* // e.g. http://www.example.com/skins/default/editor.css?t=87dm * // e.g. http://www.example.com/skins/default/editor.css?t=87dm
* alert( CKEDITOR.getUrl( '/skins/default/editor.css' ) ); * alert( CKEDITOR.getUrl( '/skins/default/editor.css' ) );
* @example * @example
* // e.g. http://www.somesite.com/skins/default/editor.css?t=87dm * // e.g. http://www.somesite.com/skins/default/editor.css?t=87dm
* alert( CKEDITOR.getUrl( 'http://www.somesite.com/skins/default/editor.css' ) ); * alert( CKEDITOR.getUrl( 'http://www.somesite.com/skins/default/editor.css' ) );
*/ */
getUrl : function( resource ) getUrl : function( resource )
{ {
// If this is not a full or absolute path. // If this is not a full or absolute path.
if ( resource.indexOf(':/') == -1 && resource.indexOf( '/' ) !== 0 ) if ( resource.indexOf(':/') == -1 && resource.indexOf( '/' ) !== 0 )
resource = this.basePath + resource; resource = this.basePath + resource;
// Add the timestamp, except for directories. // Add the timestamp, except for directories.
if ( this.timestamp && resource.charAt( resource.length - 1 ) != '/' && !(/[&?]t=/).test( resource ) ) if ( this.timestamp && resource.charAt( resource.length - 1 ) != '/' && !(/[&?]t=/).test( resource ) )
resource += ( resource.indexOf( '?' ) >= 0 ? '&' : '?' ) + 't=' + this.timestamp; resource += ( resource.indexOf( '?' ) >= 0 ? '&' : '?' ) + 't=' + this.timestamp;
return resource; return resource;
} }
}; };
// Make it possible to override the getUrl function with a custom // Make it possible to override the getUrl function with a custom
// implementation pointing to a global named CKEDITOR_GETURL. // implementation pointing to a global named CKEDITOR_GETURL.
var newGetUrl = window.CKEDITOR_GETURL; var newGetUrl = window.CKEDITOR_GETURL;
if ( newGetUrl ) if ( newGetUrl )
{ {
var originalGetUrl = CKEDITOR.getUrl; var originalGetUrl = CKEDITOR.getUrl;
CKEDITOR.getUrl = function ( resource ) CKEDITOR.getUrl = function ( resource )
{ {
return newGetUrl.call( CKEDITOR, resource ) || return newGetUrl.call( CKEDITOR, resource ) ||
originalGetUrl.call( CKEDITOR, resource ); originalGetUrl.call( CKEDITOR, resource );
}; };
} }
return CKEDITOR; return CKEDITOR;
})(); })();
} }
/** /**
* Function called upon loading a custom configuration file that can * Function called upon loading a custom configuration file that can
* modify the editor instance configuration ({@link CKEDITOR.editor#config }). * modify the editor instance configuration ({@link CKEDITOR.editor#config }).
* It is usually defined inside the custom configuration files that can * It is usually defined inside the custom configuration files that can
* include developer defined settings. * include developer defined settings.
* @name CKEDITOR.editorConfig * @name CKEDITOR.editorConfig
* @function * @function
* @param {CKEDITOR.config} config A configuration object containing the * @param {CKEDITOR.config} config A configuration object containing the
* settings defined for a {@link CKEDITOR.editor} instance up to this * settings defined for a {@link CKEDITOR.editor} instance up to this
* function call. Note that not all settings may still be available. See * function call. Note that not all settings may still be available. See
* <a href="http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Setting_Configurations#Configuration_Loading_Order">Configuration Loading Order</a> * <a href="http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Setting_Configurations#Configuration_Loading_Order">Configuration Loading Order</a>
* for details. * for details.
* @example * @example
* // This is supposed to be placed in the config.js file. * // This is supposed to be placed in the config.js file.
* CKEDITOR.editorConfig = function( config ) * CKEDITOR.editorConfig = function( config )
* { * {
* // Define changes to default configuration here. For example: * // Define changes to default configuration here. For example:
* config.language = 'fr'; * config.language = 'fr';
* config.uiColor = '#AADC6E'; * config.uiColor = '#AADC6E';
* }; * };
*/ */
// PACKAGER_RENAME( CKEDITOR ) // PACKAGER_RENAME( CKEDITOR )

View File

@@ -1,238 +1,238 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Contains the second part of the {@link CKEDITOR} object * @fileOverview Contains the second part of the {@link CKEDITOR} object
* definition, which defines the basic editor features to be available in * definition, which defines the basic editor features to be available in
* the root ckeditor_basic.js file. * the root ckeditor_basic.js file.
*/ */
if ( CKEDITOR.status == 'unloaded' ) if ( CKEDITOR.status == 'unloaded' )
{ {
(function() (function()
{ {
CKEDITOR.event.implementOn( CKEDITOR ); CKEDITOR.event.implementOn( CKEDITOR );
/** /**
* Forces the full CKEditor core code, in the case only the basic code has been * Forces the full CKEditor core code, in the case only the basic code has been
* loaded (ckeditor_basic.js). This method self-destroys (becomes undefined) in * loaded (ckeditor_basic.js). This method self-destroys (becomes undefined) in
* the first call or as soon as the full code is available. * the first call or as soon as the full code is available.
* @example * @example
* // Check if the full core code has been loaded and load it. * // Check if the full core code has been loaded and load it.
* if ( CKEDITOR.loadFullCore ) * if ( CKEDITOR.loadFullCore )
* <b>CKEDITOR.loadFullCore()</b>; * <b>CKEDITOR.loadFullCore()</b>;
*/ */
CKEDITOR.loadFullCore = function() CKEDITOR.loadFullCore = function()
{ {
// If not the basic code is not ready it, just mark it to be loaded. // If not the basic code is not ready it, just mark it to be loaded.
if ( CKEDITOR.status != 'basic_ready' ) if ( CKEDITOR.status != 'basic_ready' )
{ {
CKEDITOR.loadFullCore._load = 1; CKEDITOR.loadFullCore._load = 1;
return; return;
} }
// Destroy this function. // Destroy this function.
delete CKEDITOR.loadFullCore; delete CKEDITOR.loadFullCore;
// Append the script to the head. // Append the script to the head.
var script = document.createElement( 'script' ); var script = document.createElement( 'script' );
script.type = 'text/javascript'; script.type = 'text/javascript';
script.src = CKEDITOR.basePath + 'ckeditor.js'; script.src = CKEDITOR.basePath + 'ckeditor.js';
document.getElementsByTagName( 'head' )[0].appendChild( script ); document.getElementsByTagName( 'head' )[0].appendChild( script );
}; };
/** /**
* The time to wait (in seconds) to load the full editor code after the * The time to wait (in seconds) to load the full editor code after the
* page load, if the "ckeditor_basic" file is used. If set to zero, the * page load, if the "ckeditor_basic" file is used. If set to zero, the
* editor is loaded on demand, as soon as an instance is created. * editor is loaded on demand, as soon as an instance is created.
* *
* This value must be set on the page before the page load completion. * This value must be set on the page before the page load completion.
* @type Number * @type Number
* @default 0 (zero) * @default 0 (zero)
* @example * @example
* // Loads the full source after five seconds. * // Loads the full source after five seconds.
* CKEDITOR.loadFullCoreTimeout = 5; * CKEDITOR.loadFullCoreTimeout = 5;
*/ */
CKEDITOR.loadFullCoreTimeout = 0; CKEDITOR.loadFullCoreTimeout = 0;
/** /**
* The class name used to identify &lt;textarea&gt; elements to be replace * The class name used to identify &lt;textarea&gt; elements to be replace
* by CKEditor instances. * by CKEditor instances.
* @type String * @type String
* @default 'ckeditor' * @default 'ckeditor'
* @example * @example
* <b>CKEDITOR.replaceClass</b> = 'rich_editor'; * <b>CKEDITOR.replaceClass</b> = 'rich_editor';
*/ */
CKEDITOR.replaceClass = 'ckeditor'; CKEDITOR.replaceClass = 'ckeditor';
/** /**
* Enables the replacement of all textareas with class name matching * Enables the replacement of all textareas with class name matching
* {@link CKEDITOR.replaceClass}. * {@link CKEDITOR.replaceClass}.
* @type Boolean * @type Boolean
* @default true * @default true
* @example * @example
* // Disable the auto-replace feature. * // Disable the auto-replace feature.
* <b>CKEDITOR.replaceByClassEnabled</b> = false; * <b>CKEDITOR.replaceByClassEnabled</b> = false;
*/ */
CKEDITOR.replaceByClassEnabled = 1; CKEDITOR.replaceByClassEnabled = 1;
var createInstance = function( elementOrIdOrName, config, creationFunction, data ) var createInstance = function( elementOrIdOrName, config, creationFunction, data )
{ {
if ( CKEDITOR.env.isCompatible ) if ( CKEDITOR.env.isCompatible )
{ {
// Load the full core. // Load the full core.
if ( CKEDITOR.loadFullCore ) if ( CKEDITOR.loadFullCore )
CKEDITOR.loadFullCore(); CKEDITOR.loadFullCore();
var editor = creationFunction( elementOrIdOrName, config, data ); var editor = creationFunction( elementOrIdOrName, config, data );
CKEDITOR.add( editor ); CKEDITOR.add( editor );
return editor; return editor;
} }
return null; return null;
}; };
/** /**
* Replaces a &lt;textarea&gt; or a DOM element (DIV) with a CKEditor * Replaces a &lt;textarea&gt; or a DOM element (DIV) with a CKEditor
* instance. For textareas, the initial value in the editor will be the * instance. For textareas, the initial value in the editor will be the
* textarea value. For DOM elements, their innerHTML will be used * textarea value. For DOM elements, their innerHTML will be used
* instead. We recommend using TEXTAREA and DIV elements only. * instead. We recommend using TEXTAREA and DIV elements only.
* @param {Object|String} elementOrIdOrName The DOM element (textarea), its * @param {Object|String} elementOrIdOrName The DOM element (textarea), its
* ID or name. * ID or name.
* @param {Object} [config] The specific configurations to apply to this * @param {Object} [config] The specific configurations to apply to this
* editor instance. Configurations set here will override global CKEditor * editor instance. Configurations set here will override global CKEditor
* settings. * settings.
* @returns {CKEDITOR.editor} The editor instance created. * @returns {CKEDITOR.editor} The editor instance created.
* @example * @example
* &lt;textarea id="myfield" name="myfield"&gt;&lt:/textarea&gt; * &lt;textarea id="myfield" name="myfield"&gt;&lt:/textarea&gt;
* ... * ...
* <b>CKEDITOR.replace( 'myfield' )</b>; * <b>CKEDITOR.replace( 'myfield' )</b>;
* @example * @example
* var textarea = document.body.appendChild( document.createElement( 'textarea' ) ); * var textarea = document.body.appendChild( document.createElement( 'textarea' ) );
* <b>CKEDITOR.replace( textarea )</b>; * <b>CKEDITOR.replace( textarea )</b>;
*/ */
CKEDITOR.replace = function( elementOrIdOrName, config ) CKEDITOR.replace = function( elementOrIdOrName, config )
{ {
return createInstance( elementOrIdOrName, config, CKEDITOR.editor.replace ); return createInstance( elementOrIdOrName, config, CKEDITOR.editor.replace );
}; };
/** /**
* Creates a new editor instance inside a specific DOM element. * Creates a new editor instance inside a specific DOM element.
* @param {Object|String} elementOrId The DOM element or its ID. * @param {Object|String} elementOrId The DOM element or its ID.
* @param {Object} [config] The specific configurations to apply to this * @param {Object} [config] The specific configurations to apply to this
* editor instance. Configurations set here will override global CKEditor * editor instance. Configurations set here will override global CKEditor
* settings. * settings.
* @param {String} [data] Since 3.3. Initial value for the instance. * @param {String} [data] Since 3.3. Initial value for the instance.
* @returns {CKEDITOR.editor} The editor instance created. * @returns {CKEDITOR.editor} The editor instance created.
* @example * @example
* &lt;div id="editorSpace"&gt;&lt:/div&gt; * &lt;div id="editorSpace"&gt;&lt:/div&gt;
* ... * ...
* <b>CKEDITOR.appendTo( 'editorSpace' )</b>; * <b>CKEDITOR.appendTo( 'editorSpace' )</b>;
*/ */
CKEDITOR.appendTo = function( elementOrId, config, data ) CKEDITOR.appendTo = function( elementOrId, config, data )
{ {
return createInstance( elementOrId, config, CKEDITOR.editor.appendTo, data ); return createInstance( elementOrId, config, CKEDITOR.editor.appendTo, data );
}; };
// Documented at ckeditor.js. // Documented at ckeditor.js.
CKEDITOR.add = function( editor ) CKEDITOR.add = function( editor )
{ {
// For now, just put the editor in the pending list. It will be // For now, just put the editor in the pending list. It will be
// processed as soon as the full code gets loaded. // processed as soon as the full code gets loaded.
var pending = this._.pending || ( this._.pending = [] ); var pending = this._.pending || ( this._.pending = [] );
pending.push( editor ); pending.push( editor );
}; };
/** /**
* Replace all &lt;textarea&gt; elements available in the document with * Replace all &lt;textarea&gt; elements available in the document with
* editor instances. * editor instances.
* @example * @example
* // Replace all &lt;textarea&gt; elements in the page. * // Replace all &lt;textarea&gt; elements in the page.
* CKEDITOR.replaceAll(); * CKEDITOR.replaceAll();
* @example * @example
* // Replace all &lt;textarea class="myClassName"&gt; elements in the page. * // Replace all &lt;textarea class="myClassName"&gt; elements in the page.
* CKEDITOR.replaceAll( 'myClassName' ); * CKEDITOR.replaceAll( 'myClassName' );
* @example * @example
* // Selectively replace &lt;textarea&gt; elements, based on custom assertions. * // Selectively replace &lt;textarea&gt; elements, based on custom assertions.
* CKEDITOR.replaceAll( function( textarea, config ) * CKEDITOR.replaceAll( function( textarea, config )
* { * {
* // Custom code to evaluate the replace, returning false * // Custom code to evaluate the replace, returning false
* // if it must not be done. * // if it must not be done.
* // It also passes the "config" parameter, so the * // It also passes the "config" parameter, so the
* // developer can customize the instance. * // developer can customize the instance.
* } ); * } );
*/ */
CKEDITOR.replaceAll = function() CKEDITOR.replaceAll = function()
{ {
var textareas = document.getElementsByTagName( 'textarea' ); var textareas = document.getElementsByTagName( 'textarea' );
for ( var i = 0 ; i < textareas.length ; i++ ) for ( var i = 0 ; i < textareas.length ; i++ )
{ {
var config = null, var config = null,
textarea = textareas[i]; textarea = textareas[i];
// The "name" and/or "id" attribute must exist. // The "name" and/or "id" attribute must exist.
if ( !textarea.name && !textarea.id ) if ( !textarea.name && !textarea.id )
continue; continue;
if ( typeof arguments[0] == 'string' ) if ( typeof arguments[0] == 'string' )
{ {
// The textarea class name could be passed as the function // The textarea class name could be passed as the function
// parameter. // parameter.
var classRegex = new RegExp( '(?:^|\\s)' + arguments[0] + '(?:$|\\s)' ); var classRegex = new RegExp( '(?:^|\\s)' + arguments[0] + '(?:$|\\s)' );
if ( !classRegex.test( textarea.className ) ) if ( !classRegex.test( textarea.className ) )
continue; continue;
} }
else if ( typeof arguments[0] == 'function' ) else if ( typeof arguments[0] == 'function' )
{ {
// An assertion function could be passed as the function parameter. // An assertion function could be passed as the function parameter.
// It must explicitly return "false" to ignore a specific <textarea>. // It must explicitly return "false" to ignore a specific <textarea>.
config = {}; config = {};
if ( arguments[0]( textarea, config ) === false ) if ( arguments[0]( textarea, config ) === false )
continue; continue;
} }
this.replace( textarea, config ); this.replace( textarea, config );
} }
}; };
(function() (function()
{ {
var onload = function() var onload = function()
{ {
var loadFullCore = CKEDITOR.loadFullCore, var loadFullCore = CKEDITOR.loadFullCore,
loadFullCoreTimeout = CKEDITOR.loadFullCoreTimeout; loadFullCoreTimeout = CKEDITOR.loadFullCoreTimeout;
// Replace all textareas with the default class name. // Replace all textareas with the default class name.
if ( CKEDITOR.replaceByClassEnabled ) if ( CKEDITOR.replaceByClassEnabled )
CKEDITOR.replaceAll( CKEDITOR.replaceClass ); CKEDITOR.replaceAll( CKEDITOR.replaceClass );
CKEDITOR.status = 'basic_ready'; CKEDITOR.status = 'basic_ready';
if ( loadFullCore && loadFullCore._load ) if ( loadFullCore && loadFullCore._load )
loadFullCore(); loadFullCore();
else if ( loadFullCoreTimeout ) else if ( loadFullCoreTimeout )
{ {
setTimeout( function() setTimeout( function()
{ {
if ( CKEDITOR.loadFullCore ) if ( CKEDITOR.loadFullCore )
CKEDITOR.loadFullCore(); CKEDITOR.loadFullCore();
} }
, loadFullCoreTimeout * 1000 ); , loadFullCoreTimeout * 1000 );
} }
}; };
if ( window.addEventListener ) if ( window.addEventListener )
window.addEventListener( 'load', onload, false ); window.addEventListener( 'load', onload, false );
else if ( window.attachEvent ) else if ( window.attachEvent )
window.attachEvent( 'onload', onload ); window.attachEvent( 'onload', onload );
})(); })();
CKEDITOR.status = 'basic_loaded'; CKEDITOR.status = 'basic_loaded';
})(); })();
} }

View File

@@ -1,225 +1,225 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* Creates a command class instance. * Creates a command class instance.
* @class Represents a command that can be executed on an editor instance. * @class Represents a command that can be executed on an editor instance.
* @param {CKEDITOR.editor} editor The editor instance this command will be * @param {CKEDITOR.editor} editor The editor instance this command will be
* related to. * related to.
* @param {CKEDITOR.commandDefinition} commandDefinition The command * @param {CKEDITOR.commandDefinition} commandDefinition The command
* definition. * definition.
* @augments CKEDITOR.event * @augments CKEDITOR.event
* @example * @example
* var command = new CKEDITOR.command( editor, * var command = new CKEDITOR.command( editor,
* { * {
* exec : function( editor ) * exec : function( editor )
* { * {
* alert( editor.document.getBody().getHtml() ); * alert( editor.document.getBody().getHtml() );
* } * }
* }); * });
*/ */
CKEDITOR.command = function( editor, commandDefinition ) CKEDITOR.command = function( editor, commandDefinition )
{ {
/** /**
* Lists UI items that are associated to this command. This list can be * Lists UI items that are associated to this command. This list can be
* used to interact with the UI on command execution (by the execution code * used to interact with the UI on command execution (by the execution code
* itself, for example). * itself, for example).
* @type Array * @type Array
* @example * @example
* alert( 'Number of UI items associated to this command: ' + command.<b>uiItems</b>.length ); * alert( 'Number of UI items associated to this command: ' + command.<b>uiItems</b>.length );
*/ */
this.uiItems = []; this.uiItems = [];
/** /**
* Executes the command. * Executes the command.
* @param {Object} [data] Any data to pass to the command. Depends on the * @param {Object} [data] Any data to pass to the command. Depends on the
* command implementation and requirements. * command implementation and requirements.
* @returns {Boolean} A boolean indicating that the command has been * @returns {Boolean} A boolean indicating that the command has been
* successfully executed. * successfully executed.
* @example * @example
* command.<b>exec()</b>; // The command gets executed. * command.<b>exec()</b>; // The command gets executed.
*/ */
this.exec = function( data ) this.exec = function( data )
{ {
if ( this.state == CKEDITOR.TRISTATE_DISABLED ) if ( this.state == CKEDITOR.TRISTATE_DISABLED )
return false; return false;
if ( this.editorFocus ) // Give editor focus if necessary (#4355). if ( this.editorFocus ) // Give editor focus if necessary (#4355).
editor.focus(); editor.focus();
if ( this.fire( 'exec' ) === true ) if ( this.fire( 'exec' ) === true )
return true; return true;
return ( commandDefinition.exec.call( this, editor, data ) !== false ); return ( commandDefinition.exec.call( this, editor, data ) !== false );
}; };
/** /**
* Explicitly update the status of the command, by firing the {@link CKEDITOR.command#event:refresh} event, * Explicitly update the status of the command, by firing the {@link CKEDITOR.command#event:refresh} event,
* as well as invoke the {@link CKEDITOR.commandDefinition.prototype.refresh} method if defined, this method * as well as invoke the {@link CKEDITOR.commandDefinition.prototype.refresh} method if defined, this method
* is to allow different parts of the editor code to contribute in command status resolution. * is to allow different parts of the editor code to contribute in command status resolution.
*/ */
this.refresh = function() this.refresh = function()
{ {
if ( this.fire( 'refresh' ) === true ) if ( this.fire( 'refresh' ) === true )
return true; return true;
return ( commandDefinition.refresh && commandDefinition.refresh.apply( this, arguments ) !== false ); return ( commandDefinition.refresh && commandDefinition.refresh.apply( this, arguments ) !== false );
}; };
CKEDITOR.tools.extend( this, commandDefinition, CKEDITOR.tools.extend( this, commandDefinition,
// Defaults // Defaults
/** @lends CKEDITOR.command.prototype */ /** @lends CKEDITOR.command.prototype */
{ {
/** /**
* The editor modes within which the command can be executed. The * The editor modes within which the command can be executed. The
* execution will have no action if the current mode is not listed * execution will have no action if the current mode is not listed
* in this property. * in this property.
* @type Object * @type Object
* @default { wysiwyg : 1 } * @default { wysiwyg : 1 }
* @see CKEDITOR.editor.prototype.mode * @see CKEDITOR.editor.prototype.mode
* @example * @example
* // Enable the command in both WYSIWYG and Source modes. * // Enable the command in both WYSIWYG and Source modes.
* command.<b>modes</b> = { wysiwyg : 1, source : 1 }; * command.<b>modes</b> = { wysiwyg : 1, source : 1 };
* @example * @example
* // Enable the command in Source mode only. * // Enable the command in Source mode only.
* command.<b>modes</b> = { source : 1 }; * command.<b>modes</b> = { source : 1 };
*/ */
modes : { wysiwyg : 1 }, modes : { wysiwyg : 1 },
/** /**
* Indicates that the editor will get the focus before executing * Indicates that the editor will get the focus before executing
* the command. * the command.
* @type Boolean * @type Boolean
* @default true * @default true
* @example * @example
* // Do not force the editor to have focus when executing the command. * // Do not force the editor to have focus when executing the command.
* command.<b>editorFocus</b> = false; * command.<b>editorFocus</b> = false;
*/ */
editorFocus : 1, editorFocus : 1,
/** /**
* Indicates the editor state. Possible values are: * Indicates the editor state. Possible values are:
* <ul> * <ul>
* <li>{@link CKEDITOR.TRISTATE_DISABLED}: the command is * <li>{@link CKEDITOR.TRISTATE_DISABLED}: the command is
* disabled. It's execution will have no effect. Same as * disabled. It's execution will have no effect. Same as
* {@link disable}.</li> * {@link disable}.</li>
* <li>{@link CKEDITOR.TRISTATE_ON}: the command is enabled * <li>{@link CKEDITOR.TRISTATE_ON}: the command is enabled
* and currently active in the editor (for context sensitive commands, * and currently active in the editor (for context sensitive commands,
* for example).</li> * for example).</li>
* <li>{@link CKEDITOR.TRISTATE_OFF}: the command is enabled * <li>{@link CKEDITOR.TRISTATE_OFF}: the command is enabled
* and currently inactive in the editor (for context sensitive * and currently inactive in the editor (for context sensitive
* commands, for example).</li> * commands, for example).</li>
* </ul> * </ul>
* Do not set this property directly, using the {@link #setState} * Do not set this property directly, using the {@link #setState}
* method instead. * method instead.
* @type Number * @type Number
* @default {@link CKEDITOR.TRISTATE_OFF} * @default {@link CKEDITOR.TRISTATE_OFF}
* @example * @example
* if ( command.<b>state</b> == CKEDITOR.TRISTATE_DISABLED ) * if ( command.<b>state</b> == CKEDITOR.TRISTATE_DISABLED )
* alert( 'This command is disabled' ); * alert( 'This command is disabled' );
*/ */
state : CKEDITOR.TRISTATE_OFF state : CKEDITOR.TRISTATE_OFF
}); });
// Call the CKEDITOR.event constructor to initialize this instance. // Call the CKEDITOR.event constructor to initialize this instance.
CKEDITOR.event.call( this ); CKEDITOR.event.call( this );
}; };
CKEDITOR.command.prototype = CKEDITOR.command.prototype =
{ {
/** /**
* Enables the command for execution. The command state (see * Enables the command for execution. The command state (see
* {@link CKEDITOR.command.prototype.state}) available before disabling it * {@link CKEDITOR.command.prototype.state}) available before disabling it
* is restored. * is restored.
* @example * @example
* command.<b>enable()</b>; * command.<b>enable()</b>;
* command.exec(); // Execute the command. * command.exec(); // Execute the command.
*/ */
enable : function() enable : function()
{ {
if ( this.state == CKEDITOR.TRISTATE_DISABLED ) if ( this.state == CKEDITOR.TRISTATE_DISABLED )
this.setState( ( !this.preserveState || ( typeof this.previousState == 'undefined' ) ) ? CKEDITOR.TRISTATE_OFF : this.previousState ); this.setState( ( !this.preserveState || ( typeof this.previousState == 'undefined' ) ) ? CKEDITOR.TRISTATE_OFF : this.previousState );
}, },
/** /**
* Disables the command for execution. The command state (see * Disables the command for execution. The command state (see
* {@link CKEDITOR.command.prototype.state}) will be set to * {@link CKEDITOR.command.prototype.state}) will be set to
* {@link CKEDITOR.TRISTATE_DISABLED}. * {@link CKEDITOR.TRISTATE_DISABLED}.
* @example * @example
* command.<b>disable()</b>; * command.<b>disable()</b>;
* command.exec(); // "false" - Nothing happens. * command.exec(); // "false" - Nothing happens.
*/ */
disable : function() disable : function()
{ {
this.setState( CKEDITOR.TRISTATE_DISABLED ); this.setState( CKEDITOR.TRISTATE_DISABLED );
}, },
/** /**
* Sets the command state. * Sets the command state.
* @param {Number} newState The new state. See {@link #state}. * @param {Number} newState The new state. See {@link #state}.
* @returns {Boolean} Returns "true" if the command state changed. * @returns {Boolean} Returns "true" if the command state changed.
* @example * @example
* command.<b>setState( CKEDITOR.TRISTATE_ON )</b>; * command.<b>setState( CKEDITOR.TRISTATE_ON )</b>;
* command.exec(); // Execute the command. * command.exec(); // Execute the command.
* command.<b>setState( CKEDITOR.TRISTATE_DISABLED )</b>; * command.<b>setState( CKEDITOR.TRISTATE_DISABLED )</b>;
* command.exec(); // "false" - Nothing happens. * command.exec(); // "false" - Nothing happens.
* command.<b>setState( CKEDITOR.TRISTATE_OFF )</b>; * command.<b>setState( CKEDITOR.TRISTATE_OFF )</b>;
* command.exec(); // Execute the command. * command.exec(); // Execute the command.
*/ */
setState : function( newState ) setState : function( newState )
{ {
// Do nothing if there is no state change. // Do nothing if there is no state change.
if ( this.state == newState ) if ( this.state == newState )
return false; return false;
this.previousState = this.state; this.previousState = this.state;
// Set the new state. // Set the new state.
this.state = newState; this.state = newState;
// Fire the "state" event, so other parts of the code can react to the // Fire the "state" event, so other parts of the code can react to the
// change. // change.
this.fire( 'state' ); this.fire( 'state' );
return true; return true;
}, },
/** /**
* Toggles the on/off (active/inactive) state of the command. This is * Toggles the on/off (active/inactive) state of the command. This is
* mainly used internally by context sensitive commands. * mainly used internally by context sensitive commands.
* @example * @example
* command.<b>toggleState()</b>; * command.<b>toggleState()</b>;
*/ */
toggleState : function() toggleState : function()
{ {
if ( this.state == CKEDITOR.TRISTATE_OFF ) if ( this.state == CKEDITOR.TRISTATE_OFF )
this.setState( CKEDITOR.TRISTATE_ON ); this.setState( CKEDITOR.TRISTATE_ON );
else if ( this.state == CKEDITOR.TRISTATE_ON ) else if ( this.state == CKEDITOR.TRISTATE_ON )
this.setState( CKEDITOR.TRISTATE_OFF ); this.setState( CKEDITOR.TRISTATE_OFF );
} }
}; };
CKEDITOR.event.implementOn( CKEDITOR.command.prototype, true ); CKEDITOR.event.implementOn( CKEDITOR.command.prototype, true );
/** /**
* Indicates the previous command state. * Indicates the previous command state.
* @name CKEDITOR.command.prototype.previousState * @name CKEDITOR.command.prototype.previousState
* @type Number * @type Number
* @see #state * @see #state
* @example * @example
* alert( command.<b>previousState</b> ); * alert( command.<b>previousState</b> );
*/ */
/** /**
* Fired when the command state changes. * Fired when the command state changes.
* @name CKEDITOR.command#state * @name CKEDITOR.command#state
* @event * @event
* @example * @example
* command.on( <b>'state'</b> , function( e ) * command.on( <b>'state'</b> , function( e )
* { * {
* // Alerts the new state. * // Alerts the new state.
* alert( this.state ); * alert( this.state );
* }); * });
*/ */

View File

@@ -1,129 +1,129 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the "virtual" {@link CKEDITOR.commandDefinition} class, * @fileOverview Defines the "virtual" {@link CKEDITOR.commandDefinition} class,
* which contains the defintion of a command. This file is for * which contains the defintion of a command. This file is for
* documentation purposes only. * documentation purposes only.
*/ */
/** /**
* (Virtual Class) Do not call this constructor. This class is not really part * (Virtual Class) Do not call this constructor. This class is not really part
* of the API. * of the API.
* @name CKEDITOR.commandDefinition * @name CKEDITOR.commandDefinition
* @class Virtual class that illustrates the features of command objects to be * @class Virtual class that illustrates the features of command objects to be
* passed to the {@link CKEDITOR.editor.prototype.addCommand} function. * passed to the {@link CKEDITOR.editor.prototype.addCommand} function.
* @example * @example
*/ */
/** /**
* The function to be fired when the commend is executed. * The function to be fired when the commend is executed.
* @name CKEDITOR.commandDefinition.prototype.exec * @name CKEDITOR.commandDefinition.prototype.exec
* @function * @function
* @param {CKEDITOR.editor} editor The editor within which run the command. * @param {CKEDITOR.editor} editor The editor within which run the command.
* @param {Object} [data] Additional data to be used to execute the command. * @param {Object} [data] Additional data to be used to execute the command.
* @returns {Boolean} Whether the command has been successfully executed. * @returns {Boolean} Whether the command has been successfully executed.
* Defaults to "true", if nothing is returned. * Defaults to "true", if nothing is returned.
* @example * @example
* editorInstance.addCommand( 'sample', * editorInstance.addCommand( 'sample',
* { * {
* exec : function( editor ) * exec : function( editor )
* { * {
* alert( 'Executing a command for the editor name "' + editor.name + '"!' ); * alert( 'Executing a command for the editor name "' + editor.name + '"!' );
* } * }
* }); * });
*/ */
/** /**
* Whether the command need to be hooked into the redo/undo system. * Whether the command need to be hooked into the redo/undo system.
* @name CKEDITOR.commandDefinition.prototype.canUndo * @name CKEDITOR.commandDefinition.prototype.canUndo
* @type {Boolean} * @type {Boolean}
* @default true * @default true
* @field * @field
* @example * @example
* editorInstance.addCommand( 'alertName', * editorInstance.addCommand( 'alertName',
* { * {
* exec : function( editor ) * exec : function( editor )
* { * {
* alert( editor.name ); * alert( editor.name );
* }, * },
* canUndo : false // No support for undo/redo * canUndo : false // No support for undo/redo
* }); * });
*/ */
/** /**
* Whether the command is asynchronous, which means that the * Whether the command is asynchronous, which means that the
* {@link CKEDITOR.editor#event:afterCommandExec} event will be fired by the * {@link CKEDITOR.editor#event:afterCommandExec} event will be fired by the
* command itself manually, and that the return value of this command is not to * command itself manually, and that the return value of this command is not to
* be returned by the {@link CKEDITOR.command#exec} function. * be returned by the {@link CKEDITOR.command#exec} function.
* @name CKEDITOR.commandDefinition.prototype.async * @name CKEDITOR.commandDefinition.prototype.async
* @default false * @default false
* @type {Boolean} * @type {Boolean}
* @example * @example
* editorInstance.addCommand( 'loadOptions', * editorInstance.addCommand( 'loadOptions',
* { * {
* exec : function( editor ) * exec : function( editor )
* { * {
* // Asynchronous operation below. * // Asynchronous operation below.
* CKEDITOR.ajax.loadXml( 'data.xml', function() * CKEDITOR.ajax.loadXml( 'data.xml', function()
* { * {
* editor.fire( 'afterCommandExec' ); * editor.fire( 'afterCommandExec' );
* )); * ));
* }, * },
* async : true // The command need some time to complete after exec function returns. * async : true // The command need some time to complete after exec function returns.
* }); * });
*/ */
/** /**
* Whether the command should give focus to the editor before execution. * Whether the command should give focus to the editor before execution.
* @name CKEDITOR.commandDefinition.prototype.editorFocus * @name CKEDITOR.commandDefinition.prototype.editorFocus
* @type {Boolean} * @type {Boolean}
* @default true * @default true
* @see CKEDITOR.command#editorFocus * @see CKEDITOR.command#editorFocus
* @example * @example
* editorInstance.addCommand( 'maximize', * editorInstance.addCommand( 'maximize',
* { * {
* exec : function( editor ) * exec : function( editor )
* { * {
* // ... * // ...
* }, * },
* editorFocus : false // The command doesn't require focusing the editing document. * editorFocus : false // The command doesn't require focusing the editing document.
* }); * });
*/ */
/** /**
* Whether the command state should be set to {@link CKEDITOR.TRISTATE_DISABLED} on startup. * Whether the command state should be set to {@link CKEDITOR.TRISTATE_DISABLED} on startup.
* @name CKEDITOR.commandDefinition.prototype.startDisabled * @name CKEDITOR.commandDefinition.prototype.startDisabled
* @type {Boolean} * @type {Boolean}
* @default false * @default false
* @example * @example
* editorInstance.addCommand( 'unlink', * editorInstance.addCommand( 'unlink',
* { * {
* exec : function( editor ) * exec : function( editor )
* { * {
* // ... * // ...
* }, * },
* startDisabled : true // Command is unavailable until selection is inside a link. * startDisabled : true // Command is unavailable until selection is inside a link.
* }); * });
*/ */
/** /**
* The editor modes within which the command can be executed. The execution * The editor modes within which the command can be executed. The execution
* will have no action if the current mode is not listed in this property. * will have no action if the current mode is not listed in this property.
* @name CKEDITOR.commandDefinition.prototype.modes * @name CKEDITOR.commandDefinition.prototype.modes
* @type Object * @type Object
* @default { wysiwyg : 1 } * @default { wysiwyg : 1 }
* @see CKEDITOR.command#modes * @see CKEDITOR.command#modes
* @example * @example
* editorInstance.addCommand( 'link', * editorInstance.addCommand( 'link',
* { * {
* exec : function( editor ) * exec : function( editor )
* { * {
* // ... * // ...
* }, * },
* modes : { wysiwyg : 1 } // Command is available in wysiwyg mode only. * modes : { wysiwyg : 1 } // Command is available in wysiwyg mode only.
* }); * });
*/ */

View File

@@ -1,447 +1,447 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the <code>{@link CKEDITOR.config}</code> object that stores the * @fileOverview Defines the <code>{@link CKEDITOR.config}</code> object that stores the
* default configuration settings. * default configuration settings.
*/ */
/** /**
* Used in conjunction with <code>{@link CKEDITOR.config.enterMode}</code> * Used in conjunction with <code>{@link CKEDITOR.config.enterMode}</code>
* and <code>{@link CKEDITOR.config.shiftEnterMode}</code> configuration * and <code>{@link CKEDITOR.config.shiftEnterMode}</code> configuration
* settings to make the editor produce <code>&lt;p&gt;</code> tags when * settings to make the editor produce <code>&lt;p&gt;</code> tags when
* using the <em>Enter</em> key. * using the <em>Enter</em> key.
* @constant * @constant
*/ */
CKEDITOR.ENTER_P = 1; CKEDITOR.ENTER_P = 1;
/** /**
* Used in conjunction with <code>{@link CKEDITOR.config.enterMode}</code> * Used in conjunction with <code>{@link CKEDITOR.config.enterMode}</code>
* and <code>{@link CKEDITOR.config.shiftEnterMode}</code> configuration * and <code>{@link CKEDITOR.config.shiftEnterMode}</code> configuration
* settings to make the editor produce <code>&lt;br&gt;</code> tags when * settings to make the editor produce <code>&lt;br&gt;</code> tags when
* using the <em>Enter</em> key. * using the <em>Enter</em> key.
* @constant * @constant
*/ */
CKEDITOR.ENTER_BR = 2; CKEDITOR.ENTER_BR = 2;
/** /**
* Used in conjunction with <code>{@link CKEDITOR.config.enterMode}</code> * Used in conjunction with <code>{@link CKEDITOR.config.enterMode}</code>
* and <code>{@link CKEDITOR.config.shiftEnterMode}</code> configuration * and <code>{@link CKEDITOR.config.shiftEnterMode}</code> configuration
* settings to make the editor produce <code>&lt;div&gt;</code> tags when * settings to make the editor produce <code>&lt;div&gt;</code> tags when
* using the <em>Enter</em> key. * using the <em>Enter</em> key.
* @constant * @constant
*/ */
CKEDITOR.ENTER_DIV = 3; CKEDITOR.ENTER_DIV = 3;
/** /**
* @namespace Stores default configuration settings. Changes to this object are * @namespace Stores default configuration settings. Changes to this object are
* reflected in all editor instances, if not specified otherwise for a particular * reflected in all editor instances, if not specified otherwise for a particular
* instance. * instance.
*/ */
CKEDITOR.config = CKEDITOR.config =
{ {
/** /**
* The URL path for the custom configuration file to be loaded. If not * The URL path for the custom configuration file to be loaded. If not
* overloaded with inline configuration, it defaults to the <code>config.js</code> * overloaded with inline configuration, it defaults to the <code>config.js</code>
* file present in the root of the CKEditor installation directory.<br /><br /> * file present in the root of the CKEditor installation directory.<br /><br />
* *
* CKEditor will recursively load custom configuration files defined inside * CKEditor will recursively load custom configuration files defined inside
* other custom configuration files. * other custom configuration files.
* @type String * @type String
* @default <code>'<em>&lt;CKEditor folder&gt;</em>/config.js'</code> * @default <code>'<em>&lt;CKEditor folder&gt;</em>/config.js'</code>
* @example * @example
* // Load a specific configuration file. * // Load a specific configuration file.
* CKEDITOR.replace( 'myfield', { customConfig : '/myconfig.js' } ); * CKEDITOR.replace( 'myfield', { customConfig : '/myconfig.js' } );
* @example * @example
* // Do not load any custom configuration file. * // Do not load any custom configuration file.
* CKEDITOR.replace( 'myfield', { customConfig : '' } ); * CKEDITOR.replace( 'myfield', { customConfig : '' } );
*/ */
customConfig : 'config.js', customConfig : 'config.js',
/** /**
* Whether the replaced element (usually a <code>&lt;textarea&gt;</code>) * Whether the replaced element (usually a <code>&lt;textarea&gt;</code>)
* is to be updated automatically when posting the form containing the editor. * is to be updated automatically when posting the form containing the editor.
* @type Boolean * @type Boolean
* @default <code>true</code> * @default <code>true</code>
* @example * @example
* config.autoUpdateElement = true; * config.autoUpdateElement = true;
*/ */
autoUpdateElement : true, autoUpdateElement : true,
/** /**
* The base href URL used to resolve relative and absolute URLs in the * The base href URL used to resolve relative and absolute URLs in the
* editor content. * editor content.
* @type String * @type String
* @default <code>''</code> (empty) * @default <code>''</code> (empty)
* @example * @example
* config.baseHref = 'http://www.example.com/path/'; * config.baseHref = 'http://www.example.com/path/';
*/ */
baseHref : '', baseHref : '',
/** /**
* The CSS file(s) to be used to apply style to editor contents. It should * The CSS file(s) to be used to apply style to editor contents. It should
* reflect the CSS used in the final pages where the contents are to be * reflect the CSS used in the final pages where the contents are to be
* used. * used.
* @type String|Array * @type String|Array
* @default <code>'<em>&lt;CKEditor folder&gt;</em>/contents.css'</code> * @default <code>'<em>&lt;CKEditor folder&gt;</em>/contents.css'</code>
* @example * @example
* config.contentsCss = '/css/mysitestyles.css'; * config.contentsCss = '/css/mysitestyles.css';
* config.contentsCss = ['/css/mysitestyles.css', '/css/anotherfile.css']; * config.contentsCss = ['/css/mysitestyles.css', '/css/anotherfile.css'];
*/ */
contentsCss : CKEDITOR.basePath + 'contents.css', contentsCss : CKEDITOR.basePath + 'contents.css',
/** /**
* The writing direction of the language used to create the editor * The writing direction of the language used to create the editor
* contents. Allowed values are: * contents. Allowed values are:
* <ul> * <ul>
* <li><code>'ui'</code> &ndash; indicates that content direction will be the same as the user interface language direction;</li> * <li><code>'ui'</code> &ndash; indicates that content direction will be the same as the user interface language direction;</li>
* <li><code>'ltr'</code> &ndash; for Left-To-Right language (like English);</li> * <li><code>'ltr'</code> &ndash; for Left-To-Right language (like English);</li>
* <li><code>'rtl'</code> &ndash; for Right-To-Left languages (like Arabic).</li> * <li><code>'rtl'</code> &ndash; for Right-To-Left languages (like Arabic).</li>
* </ul> * </ul>
* @default <code>'ui'</code> * @default <code>'ui'</code>
* @type String * @type String
* @example * @example
* config.contentsLangDirection = 'rtl'; * config.contentsLangDirection = 'rtl';
*/ */
contentsLangDirection : 'ui', contentsLangDirection : 'ui',
/** /**
* Language code of the writing language which is used to create the editor * Language code of the writing language which is used to create the editor
* contents. * contents.
* @default Same value as editor UI language. * @default Same value as editor UI language.
* @type String * @type String
* @example * @example
* config.contentsLanguage = 'fr'; * config.contentsLanguage = 'fr';
*/ */
contentsLanguage : '', contentsLanguage : '',
/** /**
* The user interface language localization to use. If left empty, the editor * The user interface language localization to use. If left empty, the editor
* will automatically be localized to the user language. If the user language is not supported, * will automatically be localized to the user language. If the user language is not supported,
* the language specified in the <code>{@link CKEDITOR.config.defaultLanguage}</code> * the language specified in the <code>{@link CKEDITOR.config.defaultLanguage}</code>
* configuration setting is used. * configuration setting is used.
* @default <code>''</code> (empty) * @default <code>''</code> (empty)
* @type String * @type String
* @example * @example
* // Load the German interface. * // Load the German interface.
* config.language = 'de'; * config.language = 'de';
*/ */
language : '', language : '',
/** /**
* The language to be used if the <code>{@link CKEDITOR.config.language}</code> * The language to be used if the <code>{@link CKEDITOR.config.language}</code>
* setting is left empty and it is not possible to localize the editor to the user language. * setting is left empty and it is not possible to localize the editor to the user language.
* @default <code>'en'</code> * @default <code>'en'</code>
* @type String * @type String
* @example * @example
* config.defaultLanguage = 'it'; * config.defaultLanguage = 'it';
*/ */
defaultLanguage : 'en', defaultLanguage : 'en',
/** /**
* Sets the behavior of the <em>Enter</em> key. It also determines other behavior * Sets the behavior of the <em>Enter</em> key. It also determines other behavior
* rules of the editor, like whether the <code>&lt;br&gt;</code> element is to be used * rules of the editor, like whether the <code>&lt;br&gt;</code> element is to be used
* as a paragraph separator when indenting text. * as a paragraph separator when indenting text.
* The allowed values are the following constants that cause the behavior outlined below: * The allowed values are the following constants that cause the behavior outlined below:
* <ul> * <ul>
* <li><code>{@link CKEDITOR.ENTER_P}</code> (1) &ndash; new <code>&lt;p&gt;</code> paragraphs are created;</li> * <li><code>{@link CKEDITOR.ENTER_P}</code> (1) &ndash; new <code>&lt;p&gt;</code> paragraphs are created;</li>
* <li><code>{@link CKEDITOR.ENTER_BR}</code> (2) &ndash; lines are broken with <code>&lt;br&gt;</code> elements;</li> * <li><code>{@link CKEDITOR.ENTER_BR}</code> (2) &ndash; lines are broken with <code>&lt;br&gt;</code> elements;</li>
* <li><code>{@link CKEDITOR.ENTER_DIV}</code> (3) &ndash; new <code>&lt;div&gt;</code> blocks are created.</li> * <li><code>{@link CKEDITOR.ENTER_DIV}</code> (3) &ndash; new <code>&lt;div&gt;</code> blocks are created.</li>
* </ul> * </ul>
* <strong>Note</strong>: It is recommended to use the * <strong>Note</strong>: It is recommended to use the
* <code>{@link CKEDITOR.ENTER_P}</code> setting because of its semantic value and * <code>{@link CKEDITOR.ENTER_P}</code> setting because of its semantic value and
* correctness. The editor is optimized for this setting. * correctness. The editor is optimized for this setting.
* @type Number * @type Number
* @default <code>{@link CKEDITOR.ENTER_P}</code> * @default <code>{@link CKEDITOR.ENTER_P}</code>
* @example * @example
* // Not recommended. * // Not recommended.
* config.enterMode = CKEDITOR.ENTER_BR; * config.enterMode = CKEDITOR.ENTER_BR;
*/ */
enterMode : CKEDITOR.ENTER_P, enterMode : CKEDITOR.ENTER_P,
/** /**
* Force the use of <code>{@link CKEDITOR.config.enterMode}</code> as line break regardless * Force the use of <code>{@link CKEDITOR.config.enterMode}</code> as line break regardless
* of the context. If, for example, <code>{@link CKEDITOR.config.enterMode}</code> is set * of the context. If, for example, <code>{@link CKEDITOR.config.enterMode}</code> is set
* to <code>{@link CKEDITOR.ENTER_P}</code>, pressing the <em>Enter</em> key inside a * to <code>{@link CKEDITOR.ENTER_P}</code>, pressing the <em>Enter</em> key inside a
* <code>&lt;div&gt;</code> element will create a new paragraph with <code>&lt;p&gt;</code> * <code>&lt;div&gt;</code> element will create a new paragraph with <code>&lt;p&gt;</code>
* instead of a <code>&lt;div&gt;</code>. * instead of a <code>&lt;div&gt;</code>.
* @since 3.2.1 * @since 3.2.1
* @type Boolean * @type Boolean
* @default <code>false</code> * @default <code>false</code>
* @example * @example
* // Not recommended. * // Not recommended.
* config.forceEnterMode = true; * config.forceEnterMode = true;
*/ */
forceEnterMode : false, forceEnterMode : false,
/** /**
* Similarly to the <code>{@link CKEDITOR.config.enterMode}</code> setting, it defines the behavior * Similarly to the <code>{@link CKEDITOR.config.enterMode}</code> setting, it defines the behavior
* of the <em>Shift+Enter</em> key combination. * of the <em>Shift+Enter</em> key combination.
* The allowed values are the following constants the behavior outlined below: * The allowed values are the following constants the behavior outlined below:
* <ul> * <ul>
* <li><code>{@link CKEDITOR.ENTER_P}</code> (1) &ndash; new <code>&lt;p&gt;</code> paragraphs are created;</li> * <li><code>{@link CKEDITOR.ENTER_P}</code> (1) &ndash; new <code>&lt;p&gt;</code> paragraphs are created;</li>
* <li><code>{@link CKEDITOR.ENTER_BR}</code> (2) &ndash; lines are broken with <code>&lt;br&gt;</code> elements;</li> * <li><code>{@link CKEDITOR.ENTER_BR}</code> (2) &ndash; lines are broken with <code>&lt;br&gt;</code> elements;</li>
* <li><code>{@link CKEDITOR.ENTER_DIV}</code> (3) &ndash; new <code>&lt;div&gt;</code> blocks are created.</li> * <li><code>{@link CKEDITOR.ENTER_DIV}</code> (3) &ndash; new <code>&lt;div&gt;</code> blocks are created.</li>
* </ul> * </ul>
* @type Number * @type Number
* @default <code>{@link CKEDITOR.ENTER_BR}</code> * @default <code>{@link CKEDITOR.ENTER_BR}</code>
* @example * @example
* config.shiftEnterMode = CKEDITOR.ENTER_P; * config.shiftEnterMode = CKEDITOR.ENTER_P;
*/ */
shiftEnterMode : CKEDITOR.ENTER_BR, shiftEnterMode : CKEDITOR.ENTER_BR,
/** /**
* A comma separated list of plugins that are not related to editor * A comma separated list of plugins that are not related to editor
* instances. Reserved for plugins that extend the core code only.<br /><br /> * instances. Reserved for plugins that extend the core code only.<br /><br />
* *
* There are no ways to override this setting except by editing the source * There are no ways to override this setting except by editing the source
* code of CKEditor (<code>_source/core/config.js</code>). * code of CKEditor (<code>_source/core/config.js</code>).
* @type String * @type String
* @example * @example
*/ */
corePlugins : '', corePlugins : '',
/** /**
* Sets the <code>DOCTYPE</code> to be used when loading the editor content as HTML. * Sets the <code>DOCTYPE</code> to be used when loading the editor content as HTML.
* @type String * @type String
* @default <code>'&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;'</code> * @default <code>'&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;'</code>
* @example * @example
* // Set the DOCTYPE to the HTML 4 (Quirks) mode. * // Set the DOCTYPE to the HTML 4 (Quirks) mode.
* config.docType = '&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;'; * config.docType = '&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;';
*/ */
docType : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', docType : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
/** /**
* Sets the <code>id</code> attribute to be used on the <code>body</code> element * Sets the <code>id</code> attribute to be used on the <code>body</code> element
* of the editing area. This can be useful when you intend to reuse the original CSS * of the editing area. This can be useful when you intend to reuse the original CSS
* file you are using on your live website and want to assign the editor the same ID * file you are using on your live website and want to assign the editor the same ID
* as the section that will include the contents. In this way ID-specific CSS rules will * as the section that will include the contents. In this way ID-specific CSS rules will
* be enabled. * be enabled.
* @since 3.1 * @since 3.1
* @type String * @type String
* @default <code>''</code> (empty) * @default <code>''</code> (empty)
* @example * @example
* config.bodyId = 'contents_id'; * config.bodyId = 'contents_id';
*/ */
bodyId : '', bodyId : '',
/** /**
* Sets the <code>class</code> attribute to be used on the <code>body</code> element * Sets the <code>class</code> attribute to be used on the <code>body</code> element
* of the editing area. This can be useful when you intend to reuse the original CSS * of the editing area. This can be useful when you intend to reuse the original CSS
* file you are using on your live website and want to assign the editor the same class * file you are using on your live website and want to assign the editor the same class
* as the section that will include the contents. In this way class-specific CSS rules will * as the section that will include the contents. In this way class-specific CSS rules will
* be enabled. * be enabled.
* @since 3.1 * @since 3.1
* @type String * @type String
* @default <code>''</code> (empty) * @default <code>''</code> (empty)
* @example * @example
* config.bodyClass = 'contents'; * config.bodyClass = 'contents';
*/ */
bodyClass : '', bodyClass : '',
/** /**
* Indicates whether the contents to be edited are being input as a full * Indicates whether the contents to be edited are being input as a full
* HTML page. A full page includes the <code>&lt;html&gt;</code>, * HTML page. A full page includes the <code>&lt;html&gt;</code>,
* <code>&lt;head&gt;</code>, and <code>&lt;body&gt;</code> elements. * <code>&lt;head&gt;</code>, and <code>&lt;body&gt;</code> elements.
* The final output will also reflect this setting, including the * The final output will also reflect this setting, including the
* <code>&lt;body&gt;</code> contents only if this setting is disabled. * <code>&lt;body&gt;</code> contents only if this setting is disabled.
* @since 3.1 * @since 3.1
* @type Boolean * @type Boolean
* @default <code>false</code> * @default <code>false</code>
* @example * @example
* config.fullPage = true; * config.fullPage = true;
*/ */
fullPage : false, fullPage : false,
/** /**
* The height of the editing area (that includes the editor content). This * The height of the editing area (that includes the editor content). This
* can be an integer, for pixel sizes, or any CSS-defined length unit.<br> * can be an integer, for pixel sizes, or any CSS-defined length unit.<br>
* <br> * <br>
* <strong>Note:</strong> Percent units (%) are not supported. * <strong>Note:</strong> Percent units (%) are not supported.
* @type Number|String * @type Number|String
* @default <code>200</code> * @default <code>200</code>
* @example * @example
* config.height = 500; // 500 pixels. * config.height = 500; // 500 pixels.
* @example * @example
* config.height = '25em'; // CSS length. * config.height = '25em'; // CSS length.
* @example * @example
* config.height = '300px'; // CSS length. * config.height = '300px'; // CSS length.
*/ */
height : 200, height : 200,
/** /**
* Comma separated list of plugins to be loaded and initialized for an editor * Comma separated list of plugins to be loaded and initialized for an editor
* instance. This setting should rarely be changed. It is recommended to use the * instance. This setting should rarely be changed. It is recommended to use the
* <code>{@link CKEDITOR.config.extraPlugins}</code> and * <code>{@link CKEDITOR.config.extraPlugins}</code> and
* <code>{@link CKEDITOR.config.removePlugins}</code> for customization purposes instead. * <code>{@link CKEDITOR.config.removePlugins}</code> for customization purposes instead.
* @type String * @type String
* @example * @example
*/ */
plugins : plugins :
'about,' + 'about,' +
'a11yhelp,' + 'a11yhelp,' +
'basicstyles,' + 'basicstyles,' +
'bidi,' + 'bidi,' +
'blockquote,' + 'blockquote,' +
'button,' + 'button,' +
'clipboard,' + 'clipboard,' +
'colorbutton,' + 'colorbutton,' +
'colordialog,' + 'colordialog,' +
'contextmenu,' + 'contextmenu,' +
'dialogadvtab,' + 'dialogadvtab,' +
'div,' + 'div,' +
'elementspath,' + 'elementspath,' +
'enterkey,' + 'enterkey,' +
'entities,' + 'entities,' +
'filebrowser,' + 'filebrowser,' +
'find,' + 'find,' +
'flash,' + 'flash,' +
'font,' + 'font,' +
'format,' + 'format,' +
'forms,' + 'forms,' +
'horizontalrule,' + 'horizontalrule,' +
'htmldataprocessor,' + 'htmldataprocessor,' +
'iframe,' + 'iframe,' +
'image,' + 'image,' +
'indent,' + 'indent,' +
'justify,' + 'justify,' +
'keystrokes,' + 'keystrokes,' +
'link,' + 'link,' +
'list,' + 'list,' +
'liststyle,' + 'liststyle,' +
'maximize,' + 'maximize,' +
'newpage,' + 'newpage,' +
'pagebreak,' + 'pagebreak,' +
'pastefromword,' + 'pastefromword,' +
'pastetext,' + 'pastetext,' +
'popup,' + 'popup,' +
'preview,' + 'preview,' +
'print,' + 'print,' +
'removeformat,' + 'removeformat,' +
'resize,' + 'resize,' +
'save,' + 'save,' +
'scayt,' + 'scayt,' +
'showblocks,' + 'showblocks,' +
'showborders,' + 'showborders,' +
'smiley,' + 'smiley,' +
'sourcearea,' + 'sourcearea,' +
'specialchar,' + 'specialchar,' +
'stylescombo,' + 'stylescombo,' +
'tab,' + 'tab,' +
'table,' + 'table,' +
'tabletools,' + 'tabletools,' +
'templates,' + 'templates,' +
'toolbar,' + 'toolbar,' +
'undo,' + 'undo,' +
'wsc,' + 'wsc,' +
'wysiwygarea', 'wysiwygarea',
/** /**
* A list of additional plugins to be loaded. This setting makes it easier * A list of additional plugins to be loaded. This setting makes it easier
* to add new plugins without having to touch and potentially break the * to add new plugins without having to touch and potentially break the
* <code>{@link CKEDITOR.config.plugins}</code> setting. * <code>{@link CKEDITOR.config.plugins}</code> setting.
* @type String * @type String
* @example * @example
* config.extraPlugins = 'myplugin,anotherplugin'; * config.extraPlugins = 'myplugin,anotherplugin';
*/ */
extraPlugins : '', extraPlugins : '',
/** /**
* A list of plugins that must not be loaded. This setting makes it possible * A list of plugins that must not be loaded. This setting makes it possible
* to avoid loading some plugins defined in the <code>{@link CKEDITOR.config.plugins}</code> * to avoid loading some plugins defined in the <code>{@link CKEDITOR.config.plugins}</code>
* setting, without having to touch it and potentially break it. * setting, without having to touch it and potentially break it.
* @type String * @type String
* @example * @example
* config.removePlugins = 'elementspath,save,font'; * config.removePlugins = 'elementspath,save,font';
*/ */
removePlugins : '', removePlugins : '',
/** /**
* List of regular expressions to be executed on input HTML, * List of regular expressions to be executed on input HTML,
* indicating HTML source code that when matched, must <strong>not</strong> be available in the WYSIWYG * indicating HTML source code that when matched, must <strong>not</strong> be available in the WYSIWYG
* mode for editing. * mode for editing.
* @type Array * @type Array
* @default <code>[]</code> (empty array) * @default <code>[]</code> (empty array)
* @example * @example
* config.protectedSource.push( /<\?[\s\S]*?\?>/g ); // PHP code * config.protectedSource.push( /<\?[\s\S]*?\?>/g ); // PHP code
* config.protectedSource.push( /<%[\s\S]*?%>/g ); // ASP code * config.protectedSource.push( /<%[\s\S]*?%>/g ); // ASP code
* config.protectedSource.push( /(<asp:[^\>]+>[\s|\S]*?<\/asp:[^\>]+>)|(<asp:[^\>]+\/>)/gi ); // ASP.Net code * config.protectedSource.push( /(<asp:[^\>]+>[\s|\S]*?<\/asp:[^\>]+>)|(<asp:[^\>]+\/>)/gi ); // ASP.Net code
*/ */
protectedSource : [], protectedSource : [],
/** /**
* The editor <code>tabindex</code> value. * The editor <code>tabindex</code> value.
* @type Number * @type Number
* @default <code>0</code> (zero) * @default <code>0</code> (zero)
* @example * @example
* config.tabIndex = 1; * config.tabIndex = 1;
*/ */
tabIndex : 0, tabIndex : 0,
/** /**
* The theme to be used to build the user interface. * The theme to be used to build the user interface.
* @type String * @type String
* @default <code>'default'</code> * @default <code>'default'</code>
* @see CKEDITOR.config.skin * @see CKEDITOR.config.skin
* @example * @example
* config.theme = 'default'; * config.theme = 'default';
*/ */
theme : 'default', theme : 'default',
/** /**
* The skin to load. It may be the name of the skin folder inside the * The skin to load. It may be the name of the skin folder inside the
* editor installation path, or the name and the path separated by a comma. * editor installation path, or the name and the path separated by a comma.
* @type String * @type String
* @default <code>'default'</code> * @default <code>'default'</code>
* @example * @example
* config.skin = 'v2'; * config.skin = 'v2';
* @example * @example
* config.skin = 'myskin,/customstuff/myskin/'; * config.skin = 'myskin,/customstuff/myskin/';
*/ */
skin : 'kama', skin : 'kama',
/** /**
* The editor UI outer width. This can be an integer, for pixel sizes, or * The editor UI outer width. This can be an integer, for pixel sizes, or
* any CSS-defined unit.<br> * any CSS-defined unit.<br>
* <br> * <br>
* Unlike the <code>{@link CKEDITOR.config.height}</code> setting, this * Unlike the <code>{@link CKEDITOR.config.height}</code> setting, this
* one will set the outer width of the entire editor UI, not for the * one will set the outer width of the entire editor UI, not for the
* editing area only. * editing area only.
* @type String|Number * @type String|Number
* @default <code>''</code> (empty) * @default <code>''</code> (empty)
* @example * @example
* config.width = 850; // 850 pixels wide. * config.width = 850; // 850 pixels wide.
* @example * @example
* config.width = '75%'; // CSS unit. * config.width = '75%'; // CSS unit.
*/ */
width : '', width : '',
/** /**
* The base Z-index for floating dialog windows and popups. * The base Z-index for floating dialog windows and popups.
* @type Number * @type Number
* @default <code>10000</code> * @default <code>10000</code>
* @example * @example
* config.baseFloatZIndex = 2000 * config.baseFloatZIndex = 2000
*/ */
baseFloatZIndex : 10000 baseFloatZIndex : 10000
}; };
/** /**
* Indicates that some of the editor features, like alignment and text * Indicates that some of the editor features, like alignment and text
* direction, should use the "computed value" of the feature to indicate its * direction, should use the "computed value" of the feature to indicate its
* on/off state instead of using the "real value".<br /> * on/off state instead of using the "real value".<br />
* <br /> * <br />
* If enabled in a Left-To-Right written document, the "Left Justify" * If enabled in a Left-To-Right written document, the "Left Justify"
* alignment button will be shown as active, even if the alignment style is not * alignment button will be shown as active, even if the alignment style is not
* explicitly applied to the current paragraph in the editor. * explicitly applied to the current paragraph in the editor.
* @name CKEDITOR.config.useComputedState * @name CKEDITOR.config.useComputedState
* @type Boolean * @type Boolean
* @default <code>true</code> * @default <code>true</code>
* @since 3.4 * @since 3.4
* @example * @example
* config.useComputedState = false; * config.useComputedState = false;
*/ */
// PACKAGER_RENAME( CKEDITOR.config ) // PACKAGER_RENAME( CKEDITOR.config )

View File

@@ -1,65 +1,65 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the "virtual" {@link CKEDITOR.dataProcessor} class, which * @fileOverview Defines the "virtual" {@link CKEDITOR.dataProcessor} class, which
* defines the basic structure of data processor objects to be * defines the basic structure of data processor objects to be
* set to {@link CKEDITOR.editor.dataProcessor}. * set to {@link CKEDITOR.editor.dataProcessor}.
*/ */
/** /**
* If defined, points to the data processor which is responsible to translate * If defined, points to the data processor which is responsible to translate
* and transform the editor data on input and output. * and transform the editor data on input and output.
* Generaly it will point to an instance of {@link CKEDITOR.htmlDataProcessor}, * Generaly it will point to an instance of {@link CKEDITOR.htmlDataProcessor},
* which handles HTML data. The editor may also handle other data formats by * which handles HTML data. The editor may also handle other data formats by
* using different data processors provided by specific plugins. * using different data processors provided by specific plugins.
* @name CKEDITOR.editor.prototype.dataProcessor * @name CKEDITOR.editor.prototype.dataProcessor
* @type CKEDITOR.dataProcessor * @type CKEDITOR.dataProcessor
*/ */
/** /**
* This class is here for documentation purposes only and is not really part of * This class is here for documentation purposes only and is not really part of
* the API. It serves as the base ("interface") for data processors * the API. It serves as the base ("interface") for data processors
* implementation. * implementation.
* @name CKEDITOR.dataProcessor * @name CKEDITOR.dataProcessor
* @class Represents a data processor, which is responsible to translate and * @class Represents a data processor, which is responsible to translate and
* transform the editor data on input and output. * transform the editor data on input and output.
* @example * @example
*/ */
/** /**
* Transforms input data into HTML to be loaded in the editor. * Transforms input data into HTML to be loaded in the editor.
* While the editor is able to handle non HTML data (like BBCode), at runtime * While the editor is able to handle non HTML data (like BBCode), at runtime
* it can handle HTML data only. The role of the data processor is transforming * it can handle HTML data only. The role of the data processor is transforming
* the input data into HTML through this function. * the input data into HTML through this function.
* @name CKEDITOR.dataProcessor.prototype.toHtml * @name CKEDITOR.dataProcessor.prototype.toHtml
* @function * @function
* @param {String} data The input data to be transformed. * @param {String} data The input data to be transformed.
* @param {String} [fixForBody] The tag name to be used if the data must be * @param {String} [fixForBody] The tag name to be used if the data must be
* fixed because it is supposed to be loaded direcly into the &lt;body&gt; * fixed because it is supposed to be loaded direcly into the &lt;body&gt;
* tag. This is generally not used by non-HTML data processors. * tag. This is generally not used by non-HTML data processors.
* @example * @example
* // Tranforming BBCode data, having a custom BBCode data processor. * // Tranforming BBCode data, having a custom BBCode data processor.
* var data = 'This is [b]an example[/b].'; * var data = 'This is [b]an example[/b].';
* var html = editor.dataProcessor.toHtml( data ); // '&lt;p&gt;This is &lt;b&gt;an example&lt;/b&gt;.&lt;/p&gt;' * var html = editor.dataProcessor.toHtml( data ); // '&lt;p&gt;This is &lt;b&gt;an example&lt;/b&gt;.&lt;/p&gt;'
*/ */
/** /**
* Transforms HTML into data to be outputted by the editor, in the format * Transforms HTML into data to be outputted by the editor, in the format
* expected by the data processor. * expected by the data processor.
* While the editor is able to handle non HTML data (like BBCode), at runtime * While the editor is able to handle non HTML data (like BBCode), at runtime
* it can handle HTML data only. The role of the data processor is transforming * it can handle HTML data only. The role of the data processor is transforming
* the HTML data containined by the editor into a specific data format through * the HTML data containined by the editor into a specific data format through
* this function. * this function.
* @name CKEDITOR.dataProcessor.prototype.toDataFormat * @name CKEDITOR.dataProcessor.prototype.toDataFormat
* @function * @function
* @param {String} html The HTML to be transformed. * @param {String} html The HTML to be transformed.
* @param {String} fixForBody The tag name to be used if the output data is * @param {String} fixForBody The tag name to be used if the output data is
* coming from &lt;body&gt; and may be eventually fixed for it. This is * coming from &lt;body&gt; and may be eventually fixed for it. This is
* generally not used by non-HTML data processors. * generally not used by non-HTML data processors.
* // Tranforming into BBCode data, having a custom BBCode data processor. * // Tranforming into BBCode data, having a custom BBCode data processor.
* var html = '&lt;p&gt;This is &lt;b&gt;an example&lt;/b&gt;.&lt;/p&gt;'; * var html = '&lt;p&gt;This is &lt;b&gt;an example&lt;/b&gt;.&lt;/p&gt;';
* var data = editor.dataProcessor.toDataFormat( html ); // 'This is [b]an example[/b].' * var data = editor.dataProcessor.toDataFormat( html ); // 'This is [b]an example[/b].'
*/ */

View File

@@ -1,20 +1,20 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.dom} object, which contains DOM * @fileOverview Defines the {@link CKEDITOR.dom} object, which contains DOM
* manipulation objects and function. * manipulation objects and function.
*/ */
/** /**
* @namespace DOM manipulation objects, classes and functions. * @namespace DOM manipulation objects, classes and functions.
* @see CKEDITOR.dom.element * @see CKEDITOR.dom.element
* @see CKEDITOR.dom.node * @see CKEDITOR.dom.node
* @example * @example
*/ */
CKEDITOR.dom = CKEDITOR.dom =
{}; {};
// PACKAGER_RENAME( CKEDITOR.dom ) // PACKAGER_RENAME( CKEDITOR.dom )

View File

@@ -1,44 +1,44 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.dom.comment} class, which represents * @fileOverview Defines the {@link CKEDITOR.dom.comment} class, which represents
* a DOM comment node. * a DOM comment node.
*/ */
/** /**
* Represents a DOM comment node. * Represents a DOM comment node.
* @constructor * @constructor
* @augments CKEDITOR.dom.node * @augments CKEDITOR.dom.node
* @param {Object|String} comment A native DOM comment node or a string containing * @param {Object|String} comment A native DOM comment node or a string containing
* the text to use to create a new comment node. * the text to use to create a new comment node.
* @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain * @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
* the node in case of new node creation. Defaults to the current document. * the node in case of new node creation. Defaults to the current document.
* @example * @example
* var nativeNode = document.createComment( 'Example' ); * var nativeNode = document.createComment( 'Example' );
* var comment = CKEDITOR.dom.comment( nativeNode ); * var comment = CKEDITOR.dom.comment( nativeNode );
* @example * @example
* var comment = CKEDITOR.dom.comment( 'Example' ); * var comment = CKEDITOR.dom.comment( 'Example' );
*/ */
CKEDITOR.dom.comment = function( comment, ownerDocument ) CKEDITOR.dom.comment = function( comment, ownerDocument )
{ {
if ( typeof comment == 'string' ) if ( typeof comment == 'string' )
comment = ( ownerDocument ? ownerDocument.$ : document ).createComment( comment ); comment = ( ownerDocument ? ownerDocument.$ : document ).createComment( comment );
CKEDITOR.dom.domObject.call( this, comment ); CKEDITOR.dom.domObject.call( this, comment );
}; };
CKEDITOR.dom.comment.prototype = new CKEDITOR.dom.node(); CKEDITOR.dom.comment.prototype = new CKEDITOR.dom.node();
CKEDITOR.tools.extend( CKEDITOR.dom.comment.prototype, CKEDITOR.tools.extend( CKEDITOR.dom.comment.prototype,
/** @lends CKEDITOR.dom.comment.prototype */ /** @lends CKEDITOR.dom.comment.prototype */
{ {
type : CKEDITOR.NODE_COMMENT, type : CKEDITOR.NODE_COMMENT,
getOuterHtml : function() getOuterHtml : function()
{ {
return '<!--' + this.$.nodeValue + '-->'; return '<!--' + this.$.nodeValue + '-->';
} }
}); });

View File

@@ -1,251 +1,251 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.dom.document} class, which * @fileOverview Defines the {@link CKEDITOR.dom.document} class, which
* represents a DOM document. * represents a DOM document.
*/ */
/** /**
* Represents a DOM document. * Represents a DOM document.
* @constructor * @constructor
* @augments CKEDITOR.dom.domObject * @augments CKEDITOR.dom.domObject
* @param {Object} domDocument A native DOM document. * @param {Object} domDocument A native DOM document.
* @example * @example
* var document = new CKEDITOR.dom.document( document ); * var document = new CKEDITOR.dom.document( document );
*/ */
CKEDITOR.dom.document = function( domDocument ) CKEDITOR.dom.document = function( domDocument )
{ {
CKEDITOR.dom.domObject.call( this, domDocument ); CKEDITOR.dom.domObject.call( this, domDocument );
}; };
// PACKAGER_RENAME( CKEDITOR.dom.document ) // PACKAGER_RENAME( CKEDITOR.dom.document )
CKEDITOR.dom.document.prototype = new CKEDITOR.dom.domObject(); CKEDITOR.dom.document.prototype = new CKEDITOR.dom.domObject();
CKEDITOR.tools.extend( CKEDITOR.dom.document.prototype, CKEDITOR.tools.extend( CKEDITOR.dom.document.prototype,
/** @lends CKEDITOR.dom.document.prototype */ /** @lends CKEDITOR.dom.document.prototype */
{ {
/** /**
* Appends a CSS file to the document. * Appends a CSS file to the document.
* @param {String} cssFileUrl The CSS file URL. * @param {String} cssFileUrl The CSS file URL.
* @example * @example
* <b>CKEDITOR.document.appendStyleSheet( '/mystyles.css' )</b>; * <b>CKEDITOR.document.appendStyleSheet( '/mystyles.css' )</b>;
*/ */
appendStyleSheet : function( cssFileUrl ) appendStyleSheet : function( cssFileUrl )
{ {
if ( this.$.createStyleSheet ) if ( this.$.createStyleSheet )
this.$.createStyleSheet( cssFileUrl ); this.$.createStyleSheet( cssFileUrl );
else else
{ {
var link = new CKEDITOR.dom.element( 'link' ); var link = new CKEDITOR.dom.element( 'link' );
link.setAttributes( link.setAttributes(
{ {
rel :'stylesheet', rel :'stylesheet',
type : 'text/css', type : 'text/css',
href : cssFileUrl href : cssFileUrl
}); });
this.getHead().append( link ); this.getHead().append( link );
} }
}, },
appendStyleText : function( cssStyleText ) appendStyleText : function( cssStyleText )
{ {
if ( this.$.createStyleSheet ) if ( this.$.createStyleSheet )
{ {
var styleSheet = this.$.createStyleSheet( "" ); var styleSheet = this.$.createStyleSheet( "" );
styleSheet.cssText = cssStyleText ; styleSheet.cssText = cssStyleText ;
} }
else else
{ {
var style = new CKEDITOR.dom.element( 'style', this ); var style = new CKEDITOR.dom.element( 'style', this );
style.append( new CKEDITOR.dom.text( cssStyleText, this ) ); style.append( new CKEDITOR.dom.text( cssStyleText, this ) );
this.getHead().append( style ); this.getHead().append( style );
} }
}, },
createElement : function( name, attribsAndStyles ) createElement : function( name, attribsAndStyles )
{ {
var element = new CKEDITOR.dom.element( name, this ); var element = new CKEDITOR.dom.element( name, this );
if ( attribsAndStyles ) if ( attribsAndStyles )
{ {
if ( attribsAndStyles.attributes ) if ( attribsAndStyles.attributes )
element.setAttributes( attribsAndStyles.attributes ); element.setAttributes( attribsAndStyles.attributes );
if ( attribsAndStyles.styles ) if ( attribsAndStyles.styles )
element.setStyles( attribsAndStyles.styles ); element.setStyles( attribsAndStyles.styles );
} }
return element; return element;
}, },
createText : function( text ) createText : function( text )
{ {
return new CKEDITOR.dom.text( text, this ); return new CKEDITOR.dom.text( text, this );
}, },
focus : function() focus : function()
{ {
this.getWindow().focus(); this.getWindow().focus();
}, },
/** /**
* Gets and element based on its id. * Gets and element based on its id.
* @param {String} elementId The element id. * @param {String} elementId The element id.
* @returns {CKEDITOR.dom.element} The element instance, or null if not found. * @returns {CKEDITOR.dom.element} The element instance, or null if not found.
* @example * @example
* var element = <b>CKEDITOR.document.getById( 'myElement' )</b>; * var element = <b>CKEDITOR.document.getById( 'myElement' )</b>;
* alert( element.getId() ); // "myElement" * alert( element.getId() ); // "myElement"
*/ */
getById : function( elementId ) getById : function( elementId )
{ {
var $ = this.$.getElementById( elementId ); var $ = this.$.getElementById( elementId );
return $ ? new CKEDITOR.dom.element( $ ) : null; return $ ? new CKEDITOR.dom.element( $ ) : null;
}, },
getByAddress : function( address, normalized ) getByAddress : function( address, normalized )
{ {
var $ = this.$.documentElement; var $ = this.$.documentElement;
for ( var i = 0 ; $ && i < address.length ; i++ ) for ( var i = 0 ; $ && i < address.length ; i++ )
{ {
var target = address[ i ]; var target = address[ i ];
if ( !normalized ) if ( !normalized )
{ {
$ = $.childNodes[ target ]; $ = $.childNodes[ target ];
continue; continue;
} }
var currentIndex = -1; var currentIndex = -1;
for (var j = 0 ; j < $.childNodes.length ; j++ ) for (var j = 0 ; j < $.childNodes.length ; j++ )
{ {
var candidate = $.childNodes[ j ]; var candidate = $.childNodes[ j ];
if ( normalized === true && if ( normalized === true &&
candidate.nodeType == 3 && candidate.nodeType == 3 &&
candidate.previousSibling && candidate.previousSibling &&
candidate.previousSibling.nodeType == 3 ) candidate.previousSibling.nodeType == 3 )
{ {
continue; continue;
} }
currentIndex++; currentIndex++;
if ( currentIndex == target ) if ( currentIndex == target )
{ {
$ = candidate; $ = candidate;
break; break;
} }
} }
} }
return $ ? new CKEDITOR.dom.node( $ ) : null; return $ ? new CKEDITOR.dom.node( $ ) : null;
}, },
getElementsByTag : function( tagName, namespace ) getElementsByTag : function( tagName, namespace )
{ {
if ( !( CKEDITOR.env.ie && ! ( document.documentMode > 8 ) ) && namespace ) if ( !( CKEDITOR.env.ie && ! ( document.documentMode > 8 ) ) && namespace )
tagName = namespace + ':' + tagName; tagName = namespace + ':' + tagName;
return new CKEDITOR.dom.nodeList( this.$.getElementsByTagName( tagName ) ); return new CKEDITOR.dom.nodeList( this.$.getElementsByTagName( tagName ) );
}, },
/** /**
* Gets the &lt;head&gt; element for this document. * Gets the &lt;head&gt; element for this document.
* @returns {CKEDITOR.dom.element} The &lt;head&gt; element. * @returns {CKEDITOR.dom.element} The &lt;head&gt; element.
* @example * @example
* var element = <b>CKEDITOR.document.getHead()</b>; * var element = <b>CKEDITOR.document.getHead()</b>;
* alert( element.getName() ); // "head" * alert( element.getName() ); // "head"
*/ */
getHead : function() getHead : function()
{ {
var head = this.$.getElementsByTagName( 'head' )[0]; var head = this.$.getElementsByTagName( 'head' )[0];
if ( !head ) if ( !head )
head = this.getDocumentElement().append( new CKEDITOR.dom.element( 'head' ), true ); head = this.getDocumentElement().append( new CKEDITOR.dom.element( 'head' ), true );
else else
head = new CKEDITOR.dom.element( head ); head = new CKEDITOR.dom.element( head );
return ( return (
this.getHead = function() this.getHead = function()
{ {
return head; return head;
})(); })();
}, },
/** /**
* Gets the &lt;body&gt; element for this document. * Gets the &lt;body&gt; element for this document.
* @returns {CKEDITOR.dom.element} The &lt;body&gt; element. * @returns {CKEDITOR.dom.element} The &lt;body&gt; element.
* @example * @example
* var element = <b>CKEDITOR.document.getBody()</b>; * var element = <b>CKEDITOR.document.getBody()</b>;
* alert( element.getName() ); // "body" * alert( element.getName() ); // "body"
*/ */
getBody : function() getBody : function()
{ {
var body = new CKEDITOR.dom.element( this.$.body ); var body = new CKEDITOR.dom.element( this.$.body );
return ( return (
this.getBody = function() this.getBody = function()
{ {
return body; return body;
})(); })();
}, },
/** /**
* Gets the DOM document element for this document. * Gets the DOM document element for this document.
* @returns {CKEDITOR.dom.element} The DOM document element. * @returns {CKEDITOR.dom.element} The DOM document element.
*/ */
getDocumentElement : function() getDocumentElement : function()
{ {
var documentElement = new CKEDITOR.dom.element( this.$.documentElement ); var documentElement = new CKEDITOR.dom.element( this.$.documentElement );
return ( return (
this.getDocumentElement = function() this.getDocumentElement = function()
{ {
return documentElement; return documentElement;
})(); })();
}, },
/** /**
* Gets the window object that holds this document. * Gets the window object that holds this document.
* @returns {CKEDITOR.dom.window} The window object. * @returns {CKEDITOR.dom.window} The window object.
*/ */
getWindow : function() getWindow : function()
{ {
var win = new CKEDITOR.dom.window( this.$.parentWindow || this.$.defaultView ); var win = new CKEDITOR.dom.window( this.$.parentWindow || this.$.defaultView );
return ( return (
this.getWindow = function() this.getWindow = function()
{ {
return win; return win;
})(); })();
}, },
/** /**
* Defines the document contents through document.write. Note that the * Defines the document contents through document.write. Note that the
* previous document contents will be lost (cleaned). * previous document contents will be lost (cleaned).
* @since 3.5 * @since 3.5
* @param {String} html The HTML defining the document contents. * @param {String} html The HTML defining the document contents.
* @example * @example
* document.write( * document.write(
* '&lt;html&gt;' + * '&lt;html&gt;' +
* '&lt;head&gt;&lt;title&gt;Sample Doc&lt;/title&gt;&lt;/head&gt;' + * '&lt;head&gt;&lt;title&gt;Sample Doc&lt;/title&gt;&lt;/head&gt;' +
* '&lt;body&gt;Document contents created by code&lt;/body&gt;' + * '&lt;body&gt;Document contents created by code&lt;/body&gt;' +
* '&lt;/html&gt;' ); * '&lt;/html&gt;' );
*/ */
write : function( html ) write : function( html )
{ {
// Don't leave any history log in IE. (#5657) // Don't leave any history log in IE. (#5657)
this.$.open( 'text/html', 'replace' ); this.$.open( 'text/html', 'replace' );
// Support for custom document.domain in IE. // Support for custom document.domain in IE.
CKEDITOR.env.isCustomDomain() && ( this.$.domain = document.domain ); CKEDITOR.env.isCustomDomain() && ( this.$.domain = document.domain );
this.$.write( html ); this.$.write( html );
this.$.close(); this.$.close();
} }
}); });

View File

@@ -1,49 +1,49 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @class DocumentFragment is a "lightweight" or "minimal" Document object. It is * @class DocumentFragment is a "lightweight" or "minimal" Document object. It is
* commonly used to extract a portion of a document's tree or to create a new * commonly used to extract a portion of a document's tree or to create a new
* fragment of a document. Various operations may take DocumentFragment objects * fragment of a document. Various operations may take DocumentFragment objects
* as arguments and results in all the child nodes of the DocumentFragment being * as arguments and results in all the child nodes of the DocumentFragment being
* moved to the child list of this node. * moved to the child list of this node.
* @param {Object} ownerDocument * @param {Object} ownerDocument
*/ */
CKEDITOR.dom.documentFragment = function( ownerDocument ) CKEDITOR.dom.documentFragment = function( ownerDocument )
{ {
ownerDocument = ownerDocument || CKEDITOR.document; ownerDocument = ownerDocument || CKEDITOR.document;
this.$ = ownerDocument.$.createDocumentFragment(); this.$ = ownerDocument.$.createDocumentFragment();
}; };
CKEDITOR.tools.extend( CKEDITOR.dom.documentFragment.prototype, CKEDITOR.tools.extend( CKEDITOR.dom.documentFragment.prototype,
CKEDITOR.dom.element.prototype, CKEDITOR.dom.element.prototype,
{ {
type : CKEDITOR.NODE_DOCUMENT_FRAGMENT, type : CKEDITOR.NODE_DOCUMENT_FRAGMENT,
insertAfterNode : function( node ) insertAfterNode : function( node )
{ {
node = node.$; node = node.$;
node.parentNode.insertBefore( this.$, node.nextSibling ); node.parentNode.insertBefore( this.$, node.nextSibling );
} }
}, },
true, true,
{ {
'append' : 1, 'append' : 1,
'appendBogus' : 1, 'appendBogus' : 1,
'getFirst' : 1, 'getFirst' : 1,
'getLast' : 1, 'getLast' : 1,
'appendTo' : 1, 'appendTo' : 1,
'moveChildren' : 1, 'moveChildren' : 1,
'insertBefore' : 1, 'insertBefore' : 1,
'insertAfterNode' : 1, 'insertAfterNode' : 1,
'replace' : 1, 'replace' : 1,
'trim' : 1, 'trim' : 1,
'type' : 1, 'type' : 1,
'ltrim' : 1, 'ltrim' : 1,
'rtrim' : 1, 'rtrim' : 1,
'getDocument' : 1, 'getDocument' : 1,
'getChildCount' : 1, 'getChildCount' : 1,
'getChild' : 1, 'getChild' : 1,
'getChildren' : 1 'getChildren' : 1
} ); } );

View File

@@ -1,258 +1,258 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.editor} class, which is the base * @fileOverview Defines the {@link CKEDITOR.editor} class, which is the base
* for other classes representing DOM objects. * for other classes representing DOM objects.
*/ */
/** /**
* Represents a DOM object. This class is not intended to be used directly. It * Represents a DOM object. This class is not intended to be used directly. It
* serves as the base class for other classes representing specific DOM * serves as the base class for other classes representing specific DOM
* objects. * objects.
* @constructor * @constructor
* @param {Object} nativeDomObject A native DOM object. * @param {Object} nativeDomObject A native DOM object.
* @augments CKEDITOR.event * @augments CKEDITOR.event
* @example * @example
*/ */
CKEDITOR.dom.domObject = function( nativeDomObject ) CKEDITOR.dom.domObject = function( nativeDomObject )
{ {
if ( nativeDomObject ) if ( nativeDomObject )
{ {
/** /**
* The native DOM object represented by this class instance. * The native DOM object represented by this class instance.
* @type Object * @type Object
* @example * @example
* var element = new CKEDITOR.dom.element( 'span' ); * var element = new CKEDITOR.dom.element( 'span' );
* alert( element.$.nodeType ); // "1" * alert( element.$.nodeType ); // "1"
*/ */
this.$ = nativeDomObject; this.$ = nativeDomObject;
} }
}; };
CKEDITOR.dom.domObject.prototype = (function() CKEDITOR.dom.domObject.prototype = (function()
{ {
// Do not define other local variables here. We want to keep the native // Do not define other local variables here. We want to keep the native
// listener closures as clean as possible. // listener closures as clean as possible.
var getNativeListener = function( domObject, eventName ) var getNativeListener = function( domObject, eventName )
{ {
return function( domEvent ) return function( domEvent )
{ {
// In FF, when reloading the page with the editor focused, it may // In FF, when reloading the page with the editor focused, it may
// throw an error because the CKEDITOR global is not anymore // throw an error because the CKEDITOR global is not anymore
// available. So, we check it here first. (#2923) // available. So, we check it here first. (#2923)
if ( typeof CKEDITOR != 'undefined' ) if ( typeof CKEDITOR != 'undefined' )
domObject.fire( eventName, new CKEDITOR.dom.event( domEvent ) ); domObject.fire( eventName, new CKEDITOR.dom.event( domEvent ) );
}; };
}; };
return /** @lends CKEDITOR.dom.domObject.prototype */ { return /** @lends CKEDITOR.dom.domObject.prototype */ {
getPrivate : function() getPrivate : function()
{ {
var priv; var priv;
// Get the main private function from the custom data. Create it if not // Get the main private function from the custom data. Create it if not
// defined. // defined.
if ( !( priv = this.getCustomData( '_' ) ) ) if ( !( priv = this.getCustomData( '_' ) ) )
this.setCustomData( '_', ( priv = {} ) ); this.setCustomData( '_', ( priv = {} ) );
return priv; return priv;
}, },
/** @ignore */ /** @ignore */
on : function( eventName ) on : function( eventName )
{ {
// We customize the "on" function here. The basic idea is that we'll have // We customize the "on" function here. The basic idea is that we'll have
// only one listener for a native event, which will then call all listeners // only one listener for a native event, which will then call all listeners
// set to the event. // set to the event.
// Get the listeners holder object. // Get the listeners holder object.
var nativeListeners = this.getCustomData( '_cke_nativeListeners' ); var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
if ( !nativeListeners ) if ( !nativeListeners )
{ {
nativeListeners = {}; nativeListeners = {};
this.setCustomData( '_cke_nativeListeners', nativeListeners ); this.setCustomData( '_cke_nativeListeners', nativeListeners );
} }
// Check if we have a listener for that event. // Check if we have a listener for that event.
if ( !nativeListeners[ eventName ] ) if ( !nativeListeners[ eventName ] )
{ {
var listener = nativeListeners[ eventName ] = getNativeListener( this, eventName ); var listener = nativeListeners[ eventName ] = getNativeListener( this, eventName );
if ( this.$.addEventListener ) if ( this.$.addEventListener )
this.$.addEventListener( eventName, listener, !!CKEDITOR.event.useCapture ); this.$.addEventListener( eventName, listener, !!CKEDITOR.event.useCapture );
else if ( this.$.attachEvent ) else if ( this.$.attachEvent )
this.$.attachEvent( 'on' + eventName, listener ); this.$.attachEvent( 'on' + eventName, listener );
} }
// Call the original implementation. // Call the original implementation.
return CKEDITOR.event.prototype.on.apply( this, arguments ); return CKEDITOR.event.prototype.on.apply( this, arguments );
}, },
/** @ignore */ /** @ignore */
removeListener : function( eventName ) removeListener : function( eventName )
{ {
// Call the original implementation. // Call the original implementation.
CKEDITOR.event.prototype.removeListener.apply( this, arguments ); CKEDITOR.event.prototype.removeListener.apply( this, arguments );
// If we don't have listeners for this event, clean the DOM up. // If we don't have listeners for this event, clean the DOM up.
if ( !this.hasListeners( eventName ) ) if ( !this.hasListeners( eventName ) )
{ {
var nativeListeners = this.getCustomData( '_cke_nativeListeners' ); var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
var listener = nativeListeners && nativeListeners[ eventName ]; var listener = nativeListeners && nativeListeners[ eventName ];
if ( listener ) if ( listener )
{ {
if ( this.$.removeEventListener ) if ( this.$.removeEventListener )
this.$.removeEventListener( eventName, listener, false ); this.$.removeEventListener( eventName, listener, false );
else if ( this.$.detachEvent ) else if ( this.$.detachEvent )
this.$.detachEvent( 'on' + eventName, listener ); this.$.detachEvent( 'on' + eventName, listener );
delete nativeListeners[ eventName ]; delete nativeListeners[ eventName ];
} }
} }
}, },
/** /**
* Removes any listener set on this object. * Removes any listener set on this object.
* To avoid memory leaks we must assure that there are no * To avoid memory leaks we must assure that there are no
* references left after the object is no longer needed. * references left after the object is no longer needed.
*/ */
removeAllListeners : function() removeAllListeners : function()
{ {
var nativeListeners = this.getCustomData( '_cke_nativeListeners' ); var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
for ( var eventName in nativeListeners ) for ( var eventName in nativeListeners )
{ {
var listener = nativeListeners[ eventName ]; var listener = nativeListeners[ eventName ];
if ( this.$.detachEvent ) if ( this.$.detachEvent )
this.$.detachEvent( 'on' + eventName, listener ); this.$.detachEvent( 'on' + eventName, listener );
else if ( this.$.removeEventListener ) else if ( this.$.removeEventListener )
this.$.removeEventListener( eventName, listener, false ); this.$.removeEventListener( eventName, listener, false );
delete nativeListeners[ eventName ]; delete nativeListeners[ eventName ];
} }
} }
}; };
})(); })();
(function( domObjectProto ) (function( domObjectProto )
{ {
var customData = {}; var customData = {};
CKEDITOR.on( 'reset', function() CKEDITOR.on( 'reset', function()
{ {
customData = {}; customData = {};
}); });
/** /**
* Determines whether the specified object is equal to the current object. * Determines whether the specified object is equal to the current object.
* @name CKEDITOR.dom.domObject.prototype.equals * @name CKEDITOR.dom.domObject.prototype.equals
* @function * @function
* @param {Object} object The object to compare with the current object. * @param {Object} object The object to compare with the current object.
* @returns {Boolean} "true" if the object is equal. * @returns {Boolean} "true" if the object is equal.
* @example * @example
* var doc = new CKEDITOR.dom.document( document ); * var doc = new CKEDITOR.dom.document( document );
* alert( doc.equals( CKEDITOR.document ) ); // "true" * alert( doc.equals( CKEDITOR.document ) ); // "true"
* alert( doc == CKEDITOR.document ); // "false" * alert( doc == CKEDITOR.document ); // "false"
*/ */
domObjectProto.equals = function( object ) domObjectProto.equals = function( object )
{ {
return ( object && object.$ === this.$ ); return ( object && object.$ === this.$ );
}; };
/** /**
* Sets a data slot value for this object. These values are shared by all * Sets a data slot value for this object. These values are shared by all
* instances pointing to that same DOM object. * instances pointing to that same DOM object.
* <strong>Note:</strong> The created data slot is only guarantied to be available on this unique dom node, * <strong>Note:</strong> The created data slot is only guarantied to be available on this unique dom node,
* thus any wish to continue access it from other element clones (either created by clone node or from innerHtml) * thus any wish to continue access it from other element clones (either created by clone node or from innerHtml)
* will fail, for such usage, please use {@link CKEDITOR.dom.element::setAttribute} instead. * will fail, for such usage, please use {@link CKEDITOR.dom.element::setAttribute} instead.
* @name CKEDITOR.dom.domObject.prototype.setCustomData * @name CKEDITOR.dom.domObject.prototype.setCustomData
* @function * @function
* @param {String} key A key used to identify the data slot. * @param {String} key A key used to identify the data slot.
* @param {Object} value The value to set to the data slot. * @param {Object} value The value to set to the data slot.
* @returns {CKEDITOR.dom.domObject} This DOM object instance. * @returns {CKEDITOR.dom.domObject} This DOM object instance.
* @see CKEDITOR.dom.domObject.prototype.getCustomData * @see CKEDITOR.dom.domObject.prototype.getCustomData
* @example * @example
* var element = new CKEDITOR.dom.element( 'span' ); * var element = new CKEDITOR.dom.element( 'span' );
* element.setCustomData( 'hasCustomData', true ); * element.setCustomData( 'hasCustomData', true );
*/ */
domObjectProto.setCustomData = function( key, value ) domObjectProto.setCustomData = function( key, value )
{ {
var expandoNumber = this.getUniqueId(), var expandoNumber = this.getUniqueId(),
dataSlot = customData[ expandoNumber ] || ( customData[ expandoNumber ] = {} ); dataSlot = customData[ expandoNumber ] || ( customData[ expandoNumber ] = {} );
dataSlot[ key ] = value; dataSlot[ key ] = value;
return this; return this;
}; };
/** /**
* Gets the value set to a data slot in this object. * Gets the value set to a data slot in this object.
* @name CKEDITOR.dom.domObject.prototype.getCustomData * @name CKEDITOR.dom.domObject.prototype.getCustomData
* @function * @function
* @param {String} key The key used to identify the data slot. * @param {String} key The key used to identify the data slot.
* @returns {Object} This value set to the data slot. * @returns {Object} This value set to the data slot.
* @see CKEDITOR.dom.domObject.prototype.setCustomData * @see CKEDITOR.dom.domObject.prototype.setCustomData
* @example * @example
* var element = new CKEDITOR.dom.element( 'span' ); * var element = new CKEDITOR.dom.element( 'span' );
* alert( element.getCustomData( 'hasCustomData' ) ); // e.g. 'true' * alert( element.getCustomData( 'hasCustomData' ) ); // e.g. 'true'
*/ */
domObjectProto.getCustomData = function( key ) domObjectProto.getCustomData = function( key )
{ {
var expandoNumber = this.$[ 'data-cke-expando' ], var expandoNumber = this.$[ 'data-cke-expando' ],
dataSlot = expandoNumber && customData[ expandoNumber ]; dataSlot = expandoNumber && customData[ expandoNumber ];
return dataSlot && dataSlot[ key ]; return dataSlot && dataSlot[ key ];
}; };
/** /**
* @name CKEDITOR.dom.domObject.prototype.removeCustomData * @name CKEDITOR.dom.domObject.prototype.removeCustomData
*/ */
domObjectProto.removeCustomData = function( key ) domObjectProto.removeCustomData = function( key )
{ {
var expandoNumber = this.$[ 'data-cke-expando' ], var expandoNumber = this.$[ 'data-cke-expando' ],
dataSlot = expandoNumber && customData[ expandoNumber ], dataSlot = expandoNumber && customData[ expandoNumber ],
retval = dataSlot && dataSlot[ key ]; retval = dataSlot && dataSlot[ key ];
if ( typeof retval != 'undefined' ) if ( typeof retval != 'undefined' )
delete dataSlot[ key ]; delete dataSlot[ key ];
return retval || null; return retval || null;
}; };
/** /**
* Removes any data stored on this object. * Removes any data stored on this object.
* To avoid memory leaks we must assure that there are no * To avoid memory leaks we must assure that there are no
* references left after the object is no longer needed. * references left after the object is no longer needed.
* @name CKEDITOR.dom.domObject.prototype.clearCustomData * @name CKEDITOR.dom.domObject.prototype.clearCustomData
* @function * @function
*/ */
domObjectProto.clearCustomData = function() domObjectProto.clearCustomData = function()
{ {
// Clear all event listeners // Clear all event listeners
this.removeAllListeners(); this.removeAllListeners();
var expandoNumber = this.$[ 'data-cke-expando' ]; var expandoNumber = this.$[ 'data-cke-expando' ];
expandoNumber && delete customData[ expandoNumber ]; expandoNumber && delete customData[ expandoNumber ];
}; };
/** /**
* Gets an ID that can be used to identiquely identify this DOM object in * Gets an ID that can be used to identiquely identify this DOM object in
* the running session. * the running session.
* @name CKEDITOR.dom.domObject.prototype.getUniqueId * @name CKEDITOR.dom.domObject.prototype.getUniqueId
* @function * @function
* @returns {Number} A unique ID. * @returns {Number} A unique ID.
*/ */
domObjectProto.getUniqueId = function() domObjectProto.getUniqueId = function()
{ {
return this.$[ 'data-cke-expando' ] || ( this.$[ 'data-cke-expando' ] = CKEDITOR.tools.getNextNumber() ); return this.$[ 'data-cke-expando' ] || ( this.$[ 'data-cke-expando' ] = CKEDITOR.tools.getNextNumber() );
}; };
// Implement CKEDITOR.event. // Implement CKEDITOR.event.
CKEDITOR.event.implementOn( domObjectProto ); CKEDITOR.event.implementOn( domObjectProto );
})( CKEDITOR.dom.domObject.prototype ); })( CKEDITOR.dom.domObject.prototype );

File diff suppressed because it is too large Load Diff

View File

@@ -1,117 +1,117 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
(function() (function()
{ {
// Elements that may be considered the "Block boundary" in an element path. // Elements that may be considered the "Block boundary" in an element path.
var pathBlockElements = { address:1,blockquote:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,li:1,dt:1,dd:1, legend:1,caption:1 }; var pathBlockElements = { address:1,blockquote:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,li:1,dt:1,dd:1, legend:1,caption:1 };
// Elements that may be considered the "Block limit" in an element path. // Elements that may be considered the "Block limit" in an element path.
var pathBlockLimitElements = { body:1,div:1,table:1,tbody:1,tr:1,td:1,th:1,form:1,fieldset:1 }; var pathBlockLimitElements = { body:1,div:1,table:1,tbody:1,tr:1,td:1,th:1,form:1,fieldset:1 };
// Check if an element contains any block element. // Check if an element contains any block element.
var checkHasBlock = function( element ) var checkHasBlock = function( element )
{ {
var childNodes = element.getChildren(); var childNodes = element.getChildren();
for ( var i = 0, count = childNodes.count() ; i < count ; i++ ) for ( var i = 0, count = childNodes.count() ; i < count ; i++ )
{ {
var child = childNodes.getItem( i ); var child = childNodes.getItem( i );
if ( child.type == CKEDITOR.NODE_ELEMENT && CKEDITOR.dtd.$block[ child.getName() ] ) if ( child.type == CKEDITOR.NODE_ELEMENT && CKEDITOR.dtd.$block[ child.getName() ] )
return true; return true;
} }
return false; return false;
}; };
/** /**
* @class * @class
*/ */
CKEDITOR.dom.elementPath = function( lastNode ) CKEDITOR.dom.elementPath = function( lastNode )
{ {
var block = null; var block = null;
var blockLimit = null; var blockLimit = null;
var elements = []; var elements = [];
var e = lastNode; var e = lastNode;
while ( e ) while ( e )
{ {
if ( e.type == CKEDITOR.NODE_ELEMENT ) if ( e.type == CKEDITOR.NODE_ELEMENT )
{ {
if ( !this.lastElement ) if ( !this.lastElement )
this.lastElement = e; this.lastElement = e;
var elementName = e.getName(); var elementName = e.getName();
if ( !blockLimit ) if ( !blockLimit )
{ {
if ( !block && pathBlockElements[ elementName ] ) if ( !block && pathBlockElements[ elementName ] )
block = e; block = e;
if ( pathBlockLimitElements[ elementName ] ) if ( pathBlockLimitElements[ elementName ] )
{ {
// DIV is considered the Block, if no block is available (#525) // DIV is considered the Block, if no block is available (#525)
// and if it doesn't contain other blocks. // and if it doesn't contain other blocks.
if ( !block && elementName == 'div' && !checkHasBlock( e ) ) if ( !block && elementName == 'div' && !checkHasBlock( e ) )
block = e; block = e;
else else
blockLimit = e; blockLimit = e;
} }
} }
elements.push( e ); elements.push( e );
if ( elementName == 'body' ) if ( elementName == 'body' )
break; break;
} }
e = e.getParent(); e = e.getParent();
} }
this.block = block; this.block = block;
this.blockLimit = blockLimit; this.blockLimit = blockLimit;
this.elements = elements; this.elements = elements;
}; };
})(); })();
CKEDITOR.dom.elementPath.prototype = CKEDITOR.dom.elementPath.prototype =
{ {
/** /**
* Compares this element path with another one. * Compares this element path with another one.
* @param {CKEDITOR.dom.elementPath} otherPath The elementPath object to be * @param {CKEDITOR.dom.elementPath} otherPath The elementPath object to be
* compared with this one. * compared with this one.
* @returns {Boolean} "true" if the paths are equal, containing the same * @returns {Boolean} "true" if the paths are equal, containing the same
* number of elements and the same elements in the same order. * number of elements and the same elements in the same order.
*/ */
compare : function( otherPath ) compare : function( otherPath )
{ {
var thisElements = this.elements; var thisElements = this.elements;
var otherElements = otherPath && otherPath.elements; var otherElements = otherPath && otherPath.elements;
if ( !otherElements || thisElements.length != otherElements.length ) if ( !otherElements || thisElements.length != otherElements.length )
return false; return false;
for ( var i = 0 ; i < thisElements.length ; i++ ) for ( var i = 0 ; i < thisElements.length ; i++ )
{ {
if ( !thisElements[ i ].equals( otherElements[ i ] ) ) if ( !thisElements[ i ].equals( otherElements[ i ] ) )
return false; return false;
} }
return true; return true;
}, },
contains : function( tagNames ) contains : function( tagNames )
{ {
var elements = this.elements; var elements = this.elements;
for ( var i = 0 ; i < elements.length ; i++ ) for ( var i = 0 ; i < elements.length ; i++ )
{ {
if ( elements[ i ].getName() in tagNames ) if ( elements[ i ].getName() in tagNames )
return elements[ i ]; return elements[ i ];
} }
return null; return null;
} }
}; };

View File

@@ -1,145 +1,145 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.dom.event} class, which * @fileOverview Defines the {@link CKEDITOR.dom.event} class, which
* represents the a native DOM event object. * represents the a native DOM event object.
*/ */
/** /**
* Represents a native DOM event object. * Represents a native DOM event object.
* @constructor * @constructor
* @param {Object} domEvent A native DOM event object. * @param {Object} domEvent A native DOM event object.
* @example * @example
*/ */
CKEDITOR.dom.event = function( domEvent ) CKEDITOR.dom.event = function( domEvent )
{ {
/** /**
* The native DOM event object represented by this class instance. * The native DOM event object represented by this class instance.
* @type Object * @type Object
* @example * @example
*/ */
this.$ = domEvent; this.$ = domEvent;
}; };
CKEDITOR.dom.event.prototype = CKEDITOR.dom.event.prototype =
{ {
/** /**
* Gets the key code associated to the event. * Gets the key code associated to the event.
* @returns {Number} The key code. * @returns {Number} The key code.
* @example * @example
* alert( event.getKey() ); "65" is "a" has been pressed * alert( event.getKey() ); "65" is "a" has been pressed
*/ */
getKey : function() getKey : function()
{ {
return this.$.keyCode || this.$.which; return this.$.keyCode || this.$.which;
}, },
/** /**
* Gets a number represeting the combination of the keys pressed during the * Gets a number represeting the combination of the keys pressed during the
* event. It is the sum with the current key code and the {@link CKEDITOR.CTRL}, * event. It is the sum with the current key code and the {@link CKEDITOR.CTRL},
* {@link CKEDITOR.SHIFT} and {@link CKEDITOR.ALT} constants. * {@link CKEDITOR.SHIFT} and {@link CKEDITOR.ALT} constants.
* @returns {Number} The number representing the keys combination. * @returns {Number} The number representing the keys combination.
* @example * @example
* alert( event.getKeystroke() == 65 ); // "a" key * alert( event.getKeystroke() == 65 ); // "a" key
* alert( event.getKeystroke() == CKEDITOR.CTRL + 65 ); // CTRL + "a" key * alert( event.getKeystroke() == CKEDITOR.CTRL + 65 ); // CTRL + "a" key
* alert( event.getKeystroke() == CKEDITOR.CTRL + CKEDITOR.SHIFT + 65 ); // CTRL + SHIFT + "a" key * alert( event.getKeystroke() == CKEDITOR.CTRL + CKEDITOR.SHIFT + 65 ); // CTRL + SHIFT + "a" key
*/ */
getKeystroke : function() getKeystroke : function()
{ {
var keystroke = this.getKey(); var keystroke = this.getKey();
if ( this.$.ctrlKey || this.$.metaKey ) if ( this.$.ctrlKey || this.$.metaKey )
keystroke += CKEDITOR.CTRL; keystroke += CKEDITOR.CTRL;
if ( this.$.shiftKey ) if ( this.$.shiftKey )
keystroke += CKEDITOR.SHIFT; keystroke += CKEDITOR.SHIFT;
if ( this.$.altKey ) if ( this.$.altKey )
keystroke += CKEDITOR.ALT; keystroke += CKEDITOR.ALT;
return keystroke; return keystroke;
}, },
/** /**
* Prevents the original behavior of the event to happen. It can optionally * Prevents the original behavior of the event to happen. It can optionally
* stop propagating the event in the event chain. * stop propagating the event in the event chain.
* @param {Boolean} [stopPropagation] Stop propagating this event in the * @param {Boolean} [stopPropagation] Stop propagating this event in the
* event chain. * event chain.
* @example * @example
* var element = CKEDITOR.document.getById( 'myElement' ); * var element = CKEDITOR.document.getById( 'myElement' );
* element.on( 'click', function( ev ) * element.on( 'click', function( ev )
* { * {
* // The DOM event object is passed by the "data" property. * // The DOM event object is passed by the "data" property.
* var domEvent = ev.data; * var domEvent = ev.data;
* // Prevent the click to chave any effect in the element. * // Prevent the click to chave any effect in the element.
* domEvent.preventDefault(); * domEvent.preventDefault();
* }); * });
*/ */
preventDefault : function( stopPropagation ) preventDefault : function( stopPropagation )
{ {
var $ = this.$; var $ = this.$;
if ( $.preventDefault ) if ( $.preventDefault )
$.preventDefault(); $.preventDefault();
else else
$.returnValue = false; $.returnValue = false;
if ( stopPropagation ) if ( stopPropagation )
this.stopPropagation(); this.stopPropagation();
}, },
stopPropagation : function() stopPropagation : function()
{ {
var $ = this.$; var $ = this.$;
if ( $.stopPropagation ) if ( $.stopPropagation )
$.stopPropagation(); $.stopPropagation();
else else
$.cancelBubble = true; $.cancelBubble = true;
}, },
/** /**
* Returns the DOM node where the event was targeted to. * Returns the DOM node where the event was targeted to.
* @returns {CKEDITOR.dom.node} The target DOM node. * @returns {CKEDITOR.dom.node} The target DOM node.
* @example * @example
* var element = CKEDITOR.document.getById( 'myElement' ); * var element = CKEDITOR.document.getById( 'myElement' );
* element.on( 'click', function( ev ) * element.on( 'click', function( ev )
* { * {
* // The DOM event object is passed by the "data" property. * // The DOM event object is passed by the "data" property.
* var domEvent = ev.data; * var domEvent = ev.data;
* // Add a CSS class to the event target. * // Add a CSS class to the event target.
* domEvent.getTarget().addClass( 'clicked' ); * domEvent.getTarget().addClass( 'clicked' );
* }); * });
*/ */
getTarget : function() getTarget : function()
{ {
var rawNode = this.$.target || this.$.srcElement; var rawNode = this.$.target || this.$.srcElement;
return rawNode ? new CKEDITOR.dom.node( rawNode ) : null; return rawNode ? new CKEDITOR.dom.node( rawNode ) : null;
} }
}; };
// For the followind constants, we need to go over the Unicode boundaries // For the followind constants, we need to go over the Unicode boundaries
// (0x10FFFF) to avoid collision. // (0x10FFFF) to avoid collision.
/** /**
* CTRL key (0x110000). * CTRL key (0x110000).
* @constant * @constant
* @example * @example
*/ */
CKEDITOR.CTRL = 0x110000; CKEDITOR.CTRL = 0x110000;
/** /**
* SHIFT key (0x220000). * SHIFT key (0x220000).
* @constant * @constant
* @example * @example
*/ */
CKEDITOR.SHIFT = 0x220000; CKEDITOR.SHIFT = 0x220000;
/** /**
* ALT key (0x440000). * ALT key (0x440000).
* @constant * @constant
* @example * @example
*/ */
CKEDITOR.ALT = 0x440000; CKEDITOR.ALT = 0x440000;

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +1,26 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @class * @class
*/ */
CKEDITOR.dom.nodeList = function( nativeList ) CKEDITOR.dom.nodeList = function( nativeList )
{ {
this.$ = nativeList; this.$ = nativeList;
}; };
CKEDITOR.dom.nodeList.prototype = CKEDITOR.dom.nodeList.prototype =
{ {
count : function() count : function()
{ {
return this.$.length; return this.$.length;
}, },
getItem : function( index ) getItem : function( index )
{ {
var $node = this.$[ index ]; var $node = this.$[ index ];
return $node ? new CKEDITOR.dom.node( $node ) : null; return $node ? new CKEDITOR.dom.node( $node ) : null;
} }
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -1,213 +1,213 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
(function() (function()
{ {
/** /**
* Represents a list os CKEDITOR.dom.range objects, which can be easily * Represents a list os CKEDITOR.dom.range objects, which can be easily
* iterated sequentially. * iterated sequentially.
* @constructor * @constructor
* @param {CKEDITOR.dom.range|Array} [ranges] The ranges contained on this list. * @param {CKEDITOR.dom.range|Array} [ranges] The ranges contained on this list.
* Note that, if an array of ranges is specified, the range sequence * Note that, if an array of ranges is specified, the range sequence
* should match its DOM order. This class will not help to sort them. * should match its DOM order. This class will not help to sort them.
*/ */
CKEDITOR.dom.rangeList = function( ranges ) CKEDITOR.dom.rangeList = function( ranges )
{ {
if ( ranges instanceof CKEDITOR.dom.rangeList ) if ( ranges instanceof CKEDITOR.dom.rangeList )
return ranges; return ranges;
if ( !ranges ) if ( !ranges )
ranges = []; ranges = [];
else if ( ranges instanceof CKEDITOR.dom.range ) else if ( ranges instanceof CKEDITOR.dom.range )
ranges = [ ranges ]; ranges = [ ranges ];
return CKEDITOR.tools.extend( ranges, mixins ); return CKEDITOR.tools.extend( ranges, mixins );
}; };
var mixins = var mixins =
/** @lends CKEDITOR.dom.rangeList.prototype */ /** @lends CKEDITOR.dom.rangeList.prototype */
{ {
/** /**
* Creates an instance of the rangeList iterator, it should be used * Creates an instance of the rangeList iterator, it should be used
* only when the ranges processing could be DOM intrusive, which * only when the ranges processing could be DOM intrusive, which
* means it may pollute and break other ranges in this list. * means it may pollute and break other ranges in this list.
* Otherwise, it's enough to just iterate over this array in a for loop. * Otherwise, it's enough to just iterate over this array in a for loop.
* @returns {CKEDITOR.dom.rangeListIterator} * @returns {CKEDITOR.dom.rangeListIterator}
*/ */
createIterator : function() createIterator : function()
{ {
var rangeList = this, var rangeList = this,
bookmark = CKEDITOR.dom.walker.bookmark(), bookmark = CKEDITOR.dom.walker.bookmark(),
guard = function( node ) { return ! ( node.is && node.is( 'tr' ) ); }, guard = function( node ) { return ! ( node.is && node.is( 'tr' ) ); },
bookmarks = [], bookmarks = [],
current; current;
/** /**
* @lends CKEDITOR.dom.rangeListIterator.prototype * @lends CKEDITOR.dom.rangeListIterator.prototype
*/ */
return { return {
/** /**
* Retrieves the next range in the list. * Retrieves the next range in the list.
* @param {Boolean} mergeConsequent Whether join two adjacent ranges into single, e.g. consequent table cells. * @param {Boolean} mergeConsequent Whether join two adjacent ranges into single, e.g. consequent table cells.
*/ */
getNextRange : function( mergeConsequent ) getNextRange : function( mergeConsequent )
{ {
current = current == undefined ? 0 : current + 1; current = current == undefined ? 0 : current + 1;
var range = rangeList[ current ]; var range = rangeList[ current ];
// Multiple ranges might be mangled by each other. // Multiple ranges might be mangled by each other.
if ( range && rangeList.length > 1 ) if ( range && rangeList.length > 1 )
{ {
// Bookmarking all other ranges on the first iteration, // Bookmarking all other ranges on the first iteration,
// the range correctness after it doesn't matter since we'll // the range correctness after it doesn't matter since we'll
// restore them before the next iteration. // restore them before the next iteration.
if ( !current ) if ( !current )
{ {
// Make sure bookmark correctness by reverse processing. // Make sure bookmark correctness by reverse processing.
for ( var i = rangeList.length - 1; i >= 0; i-- ) for ( var i = rangeList.length - 1; i >= 0; i-- )
bookmarks.unshift( rangeList[ i ].createBookmark( true ) ); bookmarks.unshift( rangeList[ i ].createBookmark( true ) );
} }
if ( mergeConsequent ) if ( mergeConsequent )
{ {
// Figure out how many ranges should be merged. // Figure out how many ranges should be merged.
var mergeCount = 0; var mergeCount = 0;
while ( rangeList[ current + mergeCount + 1 ] ) while ( rangeList[ current + mergeCount + 1 ] )
{ {
var doc = range.document, var doc = range.document,
found = 0, found = 0,
left = doc.getById( bookmarks[ mergeCount ].endNode ), left = doc.getById( bookmarks[ mergeCount ].endNode ),
right = doc.getById( bookmarks[ mergeCount + 1 ].startNode ), right = doc.getById( bookmarks[ mergeCount + 1 ].startNode ),
next; next;
// Check subsequent range. // Check subsequent range.
while ( 1 ) while ( 1 )
{ {
next = left.getNextSourceNode( false ); next = left.getNextSourceNode( false );
if ( !right.equals( next ) ) if ( !right.equals( next ) )
{ {
// This could be yet another bookmark or // This could be yet another bookmark or
// walking across block boundaries. // walking across block boundaries.
if ( bookmark( next ) || ( next.type == CKEDITOR.NODE_ELEMENT && next.isBlockBoundary() ) ) if ( bookmark( next ) || ( next.type == CKEDITOR.NODE_ELEMENT && next.isBlockBoundary() ) )
{ {
left = next; left = next;
continue; continue;
} }
} }
else else
found = 1; found = 1;
break; break;
} }
if ( !found ) if ( !found )
break; break;
mergeCount++; mergeCount++;
} }
} }
range.moveToBookmark( bookmarks.shift() ); range.moveToBookmark( bookmarks.shift() );
// Merge ranges finally after moving to bookmarks. // Merge ranges finally after moving to bookmarks.
while( mergeCount-- ) while( mergeCount-- )
{ {
next = rangeList[ ++current ]; next = rangeList[ ++current ];
next.moveToBookmark( bookmarks.shift() ); next.moveToBookmark( bookmarks.shift() );
range.setEnd( next.endContainer, next.endOffset ); range.setEnd( next.endContainer, next.endOffset );
} }
} }
return range; return range;
} }
}; };
}, },
createBookmarks : function( serializable ) createBookmarks : function( serializable )
{ {
var retval = [], bookmark; var retval = [], bookmark;
for ( var i = 0; i < this.length ; i++ ) for ( var i = 0; i < this.length ; i++ )
{ {
retval.push( bookmark = this[ i ].createBookmark( serializable, true) ); retval.push( bookmark = this[ i ].createBookmark( serializable, true) );
// Updating the container & offset values for ranges // Updating the container & offset values for ranges
// that have been touched. // that have been touched.
for ( var j = i + 1; j < this.length; j++ ) for ( var j = i + 1; j < this.length; j++ )
{ {
this[ j ] = updateDirtyRange( bookmark, this[ j ] ); this[ j ] = updateDirtyRange( bookmark, this[ j ] );
this[ j ] = updateDirtyRange( bookmark, this[ j ], true ); this[ j ] = updateDirtyRange( bookmark, this[ j ], true );
} }
} }
return retval; return retval;
}, },
createBookmarks2 : function( normalized ) createBookmarks2 : function( normalized )
{ {
var bookmarks = []; var bookmarks = [];
for ( var i = 0 ; i < this.length ; i++ ) for ( var i = 0 ; i < this.length ; i++ )
bookmarks.push( this[ i ].createBookmark2( normalized ) ); bookmarks.push( this[ i ].createBookmark2( normalized ) );
return bookmarks; return bookmarks;
}, },
/** /**
* Move each range in the list to the position specified by a list of bookmarks. * Move each range in the list to the position specified by a list of bookmarks.
* @param {Array} bookmarks The list of bookmarks, each one matching a range in the list. * @param {Array} bookmarks The list of bookmarks, each one matching a range in the list.
*/ */
moveToBookmarks : function( bookmarks ) moveToBookmarks : function( bookmarks )
{ {
for ( var i = 0 ; i < this.length ; i++ ) for ( var i = 0 ; i < this.length ; i++ )
this[ i ].moveToBookmark( bookmarks[ i ] ); this[ i ].moveToBookmark( bookmarks[ i ] );
} }
}; };
// Update the specified range which has been mangled by previous insertion of // Update the specified range which has been mangled by previous insertion of
// range bookmark nodes.(#3256) // range bookmark nodes.(#3256)
function updateDirtyRange( bookmark, dirtyRange, checkEnd ) function updateDirtyRange( bookmark, dirtyRange, checkEnd )
{ {
var serializable = bookmark.serializable, var serializable = bookmark.serializable,
container = dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ], container = dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ],
offset = checkEnd ? 'endOffset' : 'startOffset'; offset = checkEnd ? 'endOffset' : 'startOffset';
var bookmarkStart = serializable ? var bookmarkStart = serializable ?
dirtyRange.document.getById( bookmark.startNode ) dirtyRange.document.getById( bookmark.startNode )
: bookmark.startNode; : bookmark.startNode;
var bookmarkEnd = serializable ? var bookmarkEnd = serializable ?
dirtyRange.document.getById( bookmark.endNode ) dirtyRange.document.getById( bookmark.endNode )
: bookmark.endNode; : bookmark.endNode;
if ( container.equals( bookmarkStart.getPrevious() ) ) if ( container.equals( bookmarkStart.getPrevious() ) )
{ {
dirtyRange.startOffset = dirtyRange.startOffset dirtyRange.startOffset = dirtyRange.startOffset
- container.getLength() - container.getLength()
- bookmarkEnd.getPrevious().getLength(); - bookmarkEnd.getPrevious().getLength();
container = bookmarkEnd.getNext(); container = bookmarkEnd.getNext();
} }
else if ( container.equals( bookmarkEnd.getPrevious() ) ) else if ( container.equals( bookmarkEnd.getPrevious() ) )
{ {
dirtyRange.startOffset = dirtyRange.startOffset - container.getLength(); dirtyRange.startOffset = dirtyRange.startOffset - container.getLength();
container = bookmarkEnd.getNext(); container = bookmarkEnd.getNext();
} }
container.equals( bookmarkStart.getParent() ) && dirtyRange[ offset ]++; container.equals( bookmarkStart.getParent() ) && dirtyRange[ offset ]++;
container.equals( bookmarkEnd.getParent() ) && dirtyRange[ offset ]++; container.equals( bookmarkEnd.getParent() ) && dirtyRange[ offset ]++;
// Update and return this range. // Update and return this range.
dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ] = container; dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ] = container;
return dirtyRange; return dirtyRange;
} }
})(); })();
/** /**
* (Virtual Class) Do not call this constructor. This class is not really part * (Virtual Class) Do not call this constructor. This class is not really part
* of the API. It just describes the return type of {@link CKEDITOR.dom.rangeList#createIterator}. * of the API. It just describes the return type of {@link CKEDITOR.dom.rangeList#createIterator}.
* @name CKEDITOR.dom.rangeListIterator * @name CKEDITOR.dom.rangeListIterator
* @constructor * @constructor
* @example * @example
*/ */

View File

@@ -1,128 +1,128 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.dom.text} class, which represents * @fileOverview Defines the {@link CKEDITOR.dom.text} class, which represents
* a DOM text node. * a DOM text node.
*/ */
/** /**
* Represents a DOM text node. * Represents a DOM text node.
* @constructor * @constructor
* @augments CKEDITOR.dom.node * @augments CKEDITOR.dom.node
* @param {Object|String} text A native DOM text node or a string containing * @param {Object|String} text A native DOM text node or a string containing
* the text to use to create a new text node. * the text to use to create a new text node.
* @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain * @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
* the node in case of new node creation. Defaults to the current document. * the node in case of new node creation. Defaults to the current document.
* @example * @example
* var nativeNode = document.createTextNode( 'Example' ); * var nativeNode = document.createTextNode( 'Example' );
* var text = CKEDITOR.dom.text( nativeNode ); * var text = CKEDITOR.dom.text( nativeNode );
* @example * @example
* var text = CKEDITOR.dom.text( 'Example' ); * var text = CKEDITOR.dom.text( 'Example' );
*/ */
CKEDITOR.dom.text = function( text, ownerDocument ) CKEDITOR.dom.text = function( text, ownerDocument )
{ {
if ( typeof text == 'string' ) if ( typeof text == 'string' )
text = ( ownerDocument ? ownerDocument.$ : document ).createTextNode( text ); text = ( ownerDocument ? ownerDocument.$ : document ).createTextNode( text );
// Theoretically, we should call the base constructor here // Theoretically, we should call the base constructor here
// (not CKEDITOR.dom.node though). But, IE doesn't support expando // (not CKEDITOR.dom.node though). But, IE doesn't support expando
// properties on text node, so the features provided by domObject will not // properties on text node, so the features provided by domObject will not
// work for text nodes (which is not a big issue for us). // work for text nodes (which is not a big issue for us).
// //
// CKEDITOR.dom.domObject.call( this, element ); // CKEDITOR.dom.domObject.call( this, element );
/** /**
* The native DOM text node represented by this class instance. * The native DOM text node represented by this class instance.
* @type Object * @type Object
* @example * @example
* var element = new CKEDITOR.dom.text( 'Example' ); * var element = new CKEDITOR.dom.text( 'Example' );
* alert( element.$.nodeType ); // "3" * alert( element.$.nodeType ); // "3"
*/ */
this.$ = text; this.$ = text;
}; };
CKEDITOR.dom.text.prototype = new CKEDITOR.dom.node(); CKEDITOR.dom.text.prototype = new CKEDITOR.dom.node();
CKEDITOR.tools.extend( CKEDITOR.dom.text.prototype, CKEDITOR.tools.extend( CKEDITOR.dom.text.prototype,
/** @lends CKEDITOR.dom.text.prototype */ /** @lends CKEDITOR.dom.text.prototype */
{ {
/** /**
* The node type. This is a constant value set to * The node type. This is a constant value set to
* {@link CKEDITOR.NODE_TEXT}. * {@link CKEDITOR.NODE_TEXT}.
* @type Number * @type Number
* @example * @example
*/ */
type : CKEDITOR.NODE_TEXT, type : CKEDITOR.NODE_TEXT,
getLength : function() getLength : function()
{ {
return this.$.nodeValue.length; return this.$.nodeValue.length;
}, },
getText : function() getText : function()
{ {
return this.$.nodeValue; return this.$.nodeValue;
}, },
setText : function( text ) setText : function( text )
{ {
this.$.nodeValue = text; this.$.nodeValue = text;
}, },
/** /**
* Breaks this text node into two nodes at the specified offset, * Breaks this text node into two nodes at the specified offset,
* keeping both in the tree as siblings. This node then only contains * keeping both in the tree as siblings. This node then only contains
* all the content up to the offset point. A new text node, which is * all the content up to the offset point. A new text node, which is
* inserted as the next sibling of this node, contains all the content * inserted as the next sibling of this node, contains all the content
* at and after the offset point. When the offset is equal to the * at and after the offset point. When the offset is equal to the
* length of this node, the new node has no data. * length of this node, the new node has no data.
* @param {Number} The position at which to split, starting from zero. * @param {Number} The position at which to split, starting from zero.
* @returns {CKEDITOR.dom.text} The new text node. * @returns {CKEDITOR.dom.text} The new text node.
*/ */
split : function( offset ) split : function( offset )
{ {
// If the offset is after the last char, IE creates the text node // If the offset is after the last char, IE creates the text node
// on split, but don't include it into the DOM. So, we have to do // on split, but don't include it into the DOM. So, we have to do
// that manually here. // that manually here.
if ( CKEDITOR.env.ie && offset == this.getLength() ) if ( CKEDITOR.env.ie && offset == this.getLength() )
{ {
var next = this.getDocument().createText( '' ); var next = this.getDocument().createText( '' );
next.insertAfter( this ); next.insertAfter( this );
return next; return next;
} }
var doc = this.getDocument(); var doc = this.getDocument();
var retval = new CKEDITOR.dom.text( this.$.splitText( offset ), doc ); var retval = new CKEDITOR.dom.text( this.$.splitText( offset ), doc );
// IE BUG: IE8 does not update the childNodes array in DOM after splitText(), // IE BUG: IE8 does not update the childNodes array in DOM after splitText(),
// we need to make some DOM changes to make it update. (#3436) // we need to make some DOM changes to make it update. (#3436)
if ( CKEDITOR.env.ie8 ) if ( CKEDITOR.env.ie8 )
{ {
var workaround = new CKEDITOR.dom.text( '', doc ); var workaround = new CKEDITOR.dom.text( '', doc );
workaround.insertAfter( retval ); workaround.insertAfter( retval );
workaround.remove(); workaround.remove();
} }
return retval; return retval;
}, },
/** /**
* Extracts characters from indexA up to but not including indexB. * Extracts characters from indexA up to but not including indexB.
* @param {Number} indexA An integer between 0 and one less than the * @param {Number} indexA An integer between 0 and one less than the
* length of the text. * length of the text.
* @param {Number} [indexB] An integer between 0 and the length of the * @param {Number} [indexB] An integer between 0 and the length of the
* string. If omitted, extracts characters to the end of the text. * string. If omitted, extracts characters to the end of the text.
*/ */
substring : function( indexA, indexB ) substring : function( indexA, indexB )
{ {
// We need the following check due to a Firefox bug // We need the following check due to a Firefox bug
// https://bugzilla.mozilla.org/show_bug.cgi?id=458886 // https://bugzilla.mozilla.org/show_bug.cgi?id=458886
if ( typeof indexB != 'number' ) if ( typeof indexB != 'number' )
return this.$.nodeValue.substr( indexA ); return this.$.nodeValue.substr( indexA );
else else
return this.$.nodeValue.substring( indexA, indexB ); return this.$.nodeValue.substring( indexA, indexB );
} }
}); });

File diff suppressed because it is too large Load Diff

View File

@@ -1,96 +1,96 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.dom.document} class, which * @fileOverview Defines the {@link CKEDITOR.dom.document} class, which
* represents a DOM document. * represents a DOM document.
*/ */
/** /**
* Represents a DOM window. * Represents a DOM window.
* @constructor * @constructor
* @augments CKEDITOR.dom.domObject * @augments CKEDITOR.dom.domObject
* @param {Object} domWindow A native DOM window. * @param {Object} domWindow A native DOM window.
* @example * @example
* var document = new CKEDITOR.dom.window( window ); * var document = new CKEDITOR.dom.window( window );
*/ */
CKEDITOR.dom.window = function( domWindow ) CKEDITOR.dom.window = function( domWindow )
{ {
CKEDITOR.dom.domObject.call( this, domWindow ); CKEDITOR.dom.domObject.call( this, domWindow );
}; };
CKEDITOR.dom.window.prototype = new CKEDITOR.dom.domObject(); CKEDITOR.dom.window.prototype = new CKEDITOR.dom.domObject();
CKEDITOR.tools.extend( CKEDITOR.dom.window.prototype, CKEDITOR.tools.extend( CKEDITOR.dom.window.prototype,
/** @lends CKEDITOR.dom.window.prototype */ /** @lends CKEDITOR.dom.window.prototype */
{ {
/** /**
* Moves the selection focus to this window. * Moves the selection focus to this window.
* @function * @function
* @example * @example
* var win = new CKEDITOR.dom.window( window ); * var win = new CKEDITOR.dom.window( window );
* <b>win.focus()</b>; * <b>win.focus()</b>;
*/ */
focus : function() focus : function()
{ {
// Webkit is sometimes failed to focus iframe, blur it first(#3835). // Webkit is sometimes failed to focus iframe, blur it first(#3835).
if ( CKEDITOR.env.webkit && this.$.parent ) if ( CKEDITOR.env.webkit && this.$.parent )
this.$.parent.focus(); this.$.parent.focus();
this.$.focus(); this.$.focus();
}, },
/** /**
* Gets the width and height of this window's viewable area. * Gets the width and height of this window's viewable area.
* @function * @function
* @returns {Object} An object with the "width" and "height" * @returns {Object} An object with the "width" and "height"
* properties containing the size. * properties containing the size.
* @example * @example
* var win = new CKEDITOR.dom.window( window ); * var win = new CKEDITOR.dom.window( window );
* var size = <b>win.getViewPaneSize()</b>; * var size = <b>win.getViewPaneSize()</b>;
* alert( size.width ); * alert( size.width );
* alert( size.height ); * alert( size.height );
*/ */
getViewPaneSize : function() getViewPaneSize : function()
{ {
var doc = this.$.document, var doc = this.$.document,
stdMode = doc.compatMode == 'CSS1Compat'; stdMode = doc.compatMode == 'CSS1Compat';
return { return {
width : ( stdMode ? doc.documentElement.clientWidth : doc.body.clientWidth ) || 0, width : ( stdMode ? doc.documentElement.clientWidth : doc.body.clientWidth ) || 0,
height : ( stdMode ? doc.documentElement.clientHeight : doc.body.clientHeight ) || 0 height : ( stdMode ? doc.documentElement.clientHeight : doc.body.clientHeight ) || 0
}; };
}, },
/** /**
* Gets the current position of the window's scroll. * Gets the current position of the window's scroll.
* @function * @function
* @returns {Object} An object with the "x" and "y" properties * @returns {Object} An object with the "x" and "y" properties
* containing the scroll position. * containing the scroll position.
* @example * @example
* var win = new CKEDITOR.dom.window( window ); * var win = new CKEDITOR.dom.window( window );
* var pos = <b>win.getScrollPosition()</b>; * var pos = <b>win.getScrollPosition()</b>;
* alert( pos.x ); * alert( pos.x );
* alert( pos.y ); * alert( pos.y );
*/ */
getScrollPosition : function() getScrollPosition : function()
{ {
var $ = this.$; var $ = this.$;
if ( 'pageXOffset' in $ ) if ( 'pageXOffset' in $ )
{ {
return { return {
x : $.pageXOffset || 0, x : $.pageXOffset || 0,
y : $.pageYOffset || 0 y : $.pageYOffset || 0
}; };
} }
else else
{ {
var doc = $.document; var doc = $.document;
return { return {
x : doc.documentElement.scrollLeft || doc.body.scrollLeft || 0, x : doc.documentElement.scrollLeft || doc.body.scrollLeft || 0,
y : doc.documentElement.scrollTop || doc.body.scrollTop || 0 y : doc.documentElement.scrollTop || doc.body.scrollTop || 0
}; };
} }
} }
}); });

View File

@@ -1,266 +1,266 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.dtd} object, which holds the DTD * @fileOverview Defines the {@link CKEDITOR.dtd} object, which holds the DTD
* mapping for XHTML 1.0 Transitional. This file was automatically * mapping for XHTML 1.0 Transitional. This file was automatically
* generated from the file: xhtml1-transitional.dtd. * generated from the file: xhtml1-transitional.dtd.
*/ */
/** /**
* @namespace Holds and object representation of the HTML DTD to be used by the * @namespace Holds and object representation of the HTML DTD to be used by the
* editor in its internal operations.<br /> * editor in its internal operations.<br />
* <br /> * <br />
* Each element in the DTD is represented by a property in this object. Each * Each element in the DTD is represented by a property in this object. Each
* property contains the list of elements that can be contained by the element. * property contains the list of elements that can be contained by the element.
* Text is represented by the "#" property.<br /> * Text is represented by the "#" property.<br />
* <br /> * <br />
* Several special grouping properties are also available. Their names start * Several special grouping properties are also available. Their names start
* with the "$" character. * with the "$" character.
* @example * @example
* // Check if "div" can be contained in a "p" element. * // Check if "div" can be contained in a "p" element.
* alert( !!CKEDITOR.dtd[ 'p' ][ 'div' ] ); "false" * alert( !!CKEDITOR.dtd[ 'p' ][ 'div' ] ); "false"
* @example * @example
* // Check if "p" can be contained in a "div" element. * // Check if "p" can be contained in a "div" element.
* alert( !!CKEDITOR.dtd[ 'div' ][ 'p' ] ); "true" * alert( !!CKEDITOR.dtd[ 'div' ][ 'p' ] ); "true"
* @example * @example
* // Check if "p" is a block element. * // Check if "p" is a block element.
* alert( !!CKEDITOR.dtd.$block[ 'p' ] ); "true" * alert( !!CKEDITOR.dtd.$block[ 'p' ] ); "true"
*/ */
CKEDITOR.dtd = (function() CKEDITOR.dtd = (function()
{ {
var X = CKEDITOR.tools.extend, var X = CKEDITOR.tools.extend,
A = {isindex:1,fieldset:1}, A = {isindex:1,fieldset:1},
B = {input:1,button:1,select:1,textarea:1,label:1}, B = {input:1,button:1,select:1,textarea:1,label:1},
C = X({a:1},B), C = X({a:1},B),
D = X({iframe:1},C), D = X({iframe:1},C),
E = {hr:1,ul:1,menu:1,div:1,section:1,header:1,footer:1,nav:1,article:1,aside:1,figure:1,dialog:1,hgroup:1,mark:1,time:1,meter:1,command:1,keygen:1,output:1,progress:1,audio:1,video:1,details:1,datagrid:1,datalist:1,blockquote:1,noscript:1,table:1,center:1,address:1,dir:1,pre:1,h5:1,dl:1,h4:1,noframes:1,h6:1,ol:1,h1:1,h3:1,h2:1}, E = {hr:1,ul:1,menu:1,div:1,section:1,header:1,footer:1,nav:1,article:1,aside:1,figure:1,dialog:1,hgroup:1,mark:1,time:1,meter:1,command:1,keygen:1,output:1,progress:1,audio:1,video:1,details:1,datagrid:1,datalist:1,blockquote:1,noscript:1,table:1,center:1,address:1,dir:1,pre:1,h5:1,dl:1,h4:1,noframes:1,h6:1,ol:1,h1:1,h3:1,h2:1},
F = {ins:1,del:1,script:1,style:1}, F = {ins:1,del:1,script:1,style:1},
G = X({b:1,acronym:1,bdo:1,'var':1,'#':1,abbr:1,code:1,br:1,i:1,cite:1,kbd:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,dfn:1,span:1,wbr:1},F), G = X({b:1,acronym:1,bdo:1,'var':1,'#':1,abbr:1,code:1,br:1,i:1,cite:1,kbd:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,dfn:1,span:1,wbr:1},F),
H = X({sub:1,img:1,object:1,sup:1,basefont:1,map:1,applet:1,font:1,big:1,small:1,mark:1},G), H = X({sub:1,img:1,object:1,sup:1,basefont:1,map:1,applet:1,font:1,big:1,small:1,mark:1},G),
I = X({p:1},H), I = X({p:1},H),
J = X({iframe:1},H,B), J = X({iframe:1},H,B),
K = {img:1,noscript:1,br:1,kbd:1,center:1,button:1,basefont:1,h5:1,h4:1,samp:1,h6:1,ol:1,h1:1,h3:1,h2:1,form:1,font:1,'#':1,select:1,menu:1,ins:1,abbr:1,label:1,code:1,table:1,script:1,cite:1,input:1,iframe:1,strong:1,textarea:1,noframes:1,big:1,small:1,span:1,hr:1,sub:1,bdo:1,'var':1,div:1,section:1,header:1,footer:1,nav:1,article:1,aside:1,figure:1,dialog:1,hgroup:1,mark:1,time:1,meter:1,menu:1,command:1,keygen:1,output:1,progress:1,audio:1,video:1,details:1,datagrid:1,datalist:1,object:1,sup:1,strike:1,dir:1,map:1,dl:1,applet:1,del:1,isindex:1,fieldset:1,ul:1,b:1,acronym:1,a:1,blockquote:1,i:1,u:1,s:1,tt:1,address:1,q:1,pre:1,p:1,em:1,dfn:1}, K = {img:1,noscript:1,br:1,kbd:1,center:1,button:1,basefont:1,h5:1,h4:1,samp:1,h6:1,ol:1,h1:1,h3:1,h2:1,form:1,font:1,'#':1,select:1,menu:1,ins:1,abbr:1,label:1,code:1,table:1,script:1,cite:1,input:1,iframe:1,strong:1,textarea:1,noframes:1,big:1,small:1,span:1,hr:1,sub:1,bdo:1,'var':1,div:1,section:1,header:1,footer:1,nav:1,article:1,aside:1,figure:1,dialog:1,hgroup:1,mark:1,time:1,meter:1,menu:1,command:1,keygen:1,output:1,progress:1,audio:1,video:1,details:1,datagrid:1,datalist:1,object:1,sup:1,strike:1,dir:1,map:1,dl:1,applet:1,del:1,isindex:1,fieldset:1,ul:1,b:1,acronym:1,a:1,blockquote:1,i:1,u:1,s:1,tt:1,address:1,q:1,pre:1,p:1,em:1,dfn:1},
L = X({a:1},J), L = X({a:1},J),
M = {tr:1}, M = {tr:1},
N = {'#':1}, N = {'#':1},
O = X({param:1},K), O = X({param:1},K),
P = X({form:1},A,D,E,I), P = X({form:1},A,D,E,I),
Q = {li:1}, Q = {li:1},
R = {style:1,script:1}, R = {style:1,script:1},
S = {base:1,link:1,meta:1,title:1}, S = {base:1,link:1,meta:1,title:1},
T = X(S,R), T = X(S,R),
U = {head:1,body:1}, U = {head:1,body:1},
V = {html:1}; V = {html:1};
var block = {address:1,blockquote:1,center:1,dir:1,div:1,section:1,header:1,footer:1,nav:1,article:1,aside:1,figure:1,dialog:1,hgroup:1,time:1,meter:1,menu:1,command:1,keygen:1,output:1,progress:1,audio:1,video:1,details:1,datagrid:1,datalist:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,isindex:1,noframes:1,ol:1,p:1,pre:1,table:1,ul:1}; var block = {address:1,blockquote:1,center:1,dir:1,div:1,section:1,header:1,footer:1,nav:1,article:1,aside:1,figure:1,dialog:1,hgroup:1,time:1,meter:1,menu:1,command:1,keygen:1,output:1,progress:1,audio:1,video:1,details:1,datagrid:1,datalist:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,isindex:1,noframes:1,ol:1,p:1,pre:1,table:1,ul:1};
return /** @lends CKEDITOR.dtd */ { return /** @lends CKEDITOR.dtd */ {
// The "$" items have been added manually. // The "$" items have been added manually.
// List of elements living outside body. // List of elements living outside body.
$nonBodyContent: X(V,U,S), $nonBodyContent: X(V,U,S),
/** /**
* List of block elements, like "p" or "div". * List of block elements, like "p" or "div".
* @type Object * @type Object
* @example * @example
*/ */
$block : block, $block : block,
/** /**
* List of block limit elements. * List of block limit elements.
* @type Object * @type Object
* @example * @example
*/ */
$blockLimit : { body:1,div:1,section:1,header:1,footer:1,nav:1,article:1,aside:1,figure:1,dialog:1,hgroup:1,time:1,meter:1,menu:1,command:1,keygen:1,output:1,progress:1,audio:1,video:1,details:1,datagrid:1,datalist:1,td:1,th:1,caption:1,form:1 }, $blockLimit : { body:1,div:1,section:1,header:1,footer:1,nav:1,article:1,aside:1,figure:1,dialog:1,hgroup:1,time:1,meter:1,menu:1,command:1,keygen:1,output:1,progress:1,audio:1,video:1,details:1,datagrid:1,datalist:1,td:1,th:1,caption:1,form:1 },
/** /**
* List of inline (&lt;span&gt; like) elements. * List of inline (&lt;span&gt; like) elements.
*/ */
$inline : L, // Just like span. $inline : L, // Just like span.
/** /**
* list of elements that can be children at &lt;body&gt;. * list of elements that can be children at &lt;body&gt;.
*/ */
$body : X({script:1,style:1}, block), $body : X({script:1,style:1}, block),
$cdata : {script:1,style:1}, $cdata : {script:1,style:1},
/** /**
* List of empty (self-closing) elements, like "br" or "img". * List of empty (self-closing) elements, like "br" or "img".
* @type Object * @type Object
* @example * @example
*/ */
$empty : {area:1,base:1,br:1,col:1,hr:1,img:1,input:1,link:1,meta:1,param:1,wbr:1}, $empty : {area:1,base:1,br:1,col:1,hr:1,img:1,input:1,link:1,meta:1,param:1,wbr:1},
/** /**
* List of list item elements, like "li" or "dd". * List of list item elements, like "li" or "dd".
* @type Object * @type Object
* @example * @example
*/ */
$listItem : {dd:1,dt:1,li:1}, $listItem : {dd:1,dt:1,li:1},
/** /**
* List of list root elements. * List of list root elements.
* @type Object * @type Object
* @example * @example
*/ */
$list: {ul:1,ol:1,dl:1}, $list: {ul:1,ol:1,dl:1},
/** /**
* Elements that accept text nodes, but are not possible to edit into * Elements that accept text nodes, but are not possible to edit into
* the browser. * the browser.
* @type Object * @type Object
* @example * @example
*/ */
$nonEditable : {applet:1,button:1,embed:1,iframe:1,map:1,object:1,option:1,script:1,textarea:1,param:1,audio:1,video:1}, $nonEditable : {applet:1,button:1,embed:1,iframe:1,map:1,object:1,option:1,script:1,textarea:1,param:1,audio:1,video:1},
/** /**
* List of block tags with each one a singleton element lives in the corresponding structure for description. * List of block tags with each one a singleton element lives in the corresponding structure for description.
*/ */
$captionBlock : { caption:1, legend:1 }, $captionBlock : { caption:1, legend:1 },
/** /**
* List of elements that can be ignored if empty, like "b" or "span". * List of elements that can be ignored if empty, like "b" or "span".
* @type Object * @type Object
* @example * @example
*/ */
$removeEmpty : {abbr:1,acronym:1,address:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,s:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1,mark:1}, $removeEmpty : {abbr:1,acronym:1,address:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,s:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1,mark:1},
/** /**
* List of elements that have tabindex set to zero by default. * List of elements that have tabindex set to zero by default.
* @type Object * @type Object
* @example * @example
*/ */
$tabIndex : {a:1,area:1,button:1,input:1,object:1,select:1,textarea:1}, $tabIndex : {a:1,area:1,button:1,input:1,object:1,select:1,textarea:1},
/** /**
* List of elements used inside the "table" element, like "tbody" or "td". * List of elements used inside the "table" element, like "tbody" or "td".
* @type Object * @type Object
* @example * @example
*/ */
$tableContent : {caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1}, $tableContent : {caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1},
html: U, html: U,
head: T, head: T,
style: N, style: N,
script: N, script: N,
body: P, body: P,
base: {}, base: {},
link: {}, link: {},
meta: {}, meta: {},
title: N, title: N,
col : {}, col : {},
tr : {td:1,th:1}, tr : {td:1,th:1},
img : {}, img : {},
colgroup : {col:1}, colgroup : {col:1},
noscript : P, noscript : P,
td : P, td : P,
br : {}, br : {},
wbr : {}, wbr : {},
th : P, th : P,
center : P, center : P,
kbd : L, kbd : L,
button : X(I,E), button : X(I,E),
basefont : {}, basefont : {},
h5 : L, h5 : L,
h4 : L, h4 : L,
samp : L, samp : L,
h6 : L, h6 : L,
ol : Q, ol : Q,
h1 : L, h1 : L,
h3 : L, h3 : L,
option : N, option : N,
h2 : L, h2 : L,
form : X(A,D,E,I), form : X(A,D,E,I),
select : {optgroup:1,option:1}, select : {optgroup:1,option:1},
font : L, font : L,
ins : L, ins : L,
menu : Q, menu : Q,
abbr : L, abbr : L,
label : L, label : L,
table : {thead:1,col:1,tbody:1,tr:1,colgroup:1,caption:1,tfoot:1}, table : {thead:1,col:1,tbody:1,tr:1,colgroup:1,caption:1,tfoot:1},
code : L, code : L,
tfoot : M, tfoot : M,
cite : L, cite : L,
li : P, li : P,
input : {}, input : {},
iframe : P, iframe : P,
strong : L, strong : L,
textarea : N, textarea : N,
noframes : P, noframes : P,
big : L, big : L,
small : L, small : L,
span : L, span : L,
hr : {}, hr : {},
dt : L, dt : L,
sub : L, sub : L,
optgroup : {option:1}, optgroup : {option:1},
param : {}, param : {},
bdo : L, bdo : L,
'var' : L, 'var' : L,
div : P, div : P,
object : O, object : O,
sup : L, sup : L,
dd : P, dd : P,
strike : L, strike : L,
area : {}, area : {},
dir : Q, dir : Q,
map : X({area:1,form:1,p:1},A,F,E), map : X({area:1,form:1,p:1},A,F,E),
applet : O, applet : O,
dl : {dt:1,dd:1}, dl : {dt:1,dd:1},
del : L, del : L,
isindex : {}, isindex : {},
fieldset : X({legend:1},K), fieldset : X({legend:1},K),
thead : M, thead : M,
ul : Q, ul : Q,
acronym : L, acronym : L,
b : L, b : L,
a : J, a : J,
blockquote : P, blockquote : P,
caption : L, caption : L,
i : L, i : L,
u : L, u : L,
tbody : M, tbody : M,
s : L, s : L,
address : X(D,I), address : X(D,I),
tt : L, tt : L,
legend : L, legend : L,
q : L, q : L,
pre : X(G,C), pre : X(G,C),
p : L, p : L,
em : L, em : L,
dfn : L, dfn : L,
//HTML5 //HTML5
section : P, section : P,
header : P, header : P,
footer : P, footer : P,
nav : P, nav : P,
article : P, article : P,
aside : P, aside : P,
figure: P, figure: P,
dialog : P, dialog : P,
hgroup : P, hgroup : P,
mark : L, mark : L,
time : L, time : L,
meter : L, meter : L,
menu : L, menu : L,
command : L, command : L,
keygen : L, keygen : L,
output : L, output : L,
progress : O, progress : O,
audio : O, audio : O,
video : O, video : O,
details : O, details : O,
datagrid : O, datagrid : O,
datalist : O datalist : O
}; };
})(); })();
// PACKAGER_RENAME( CKEDITOR.dtd ) // PACKAGER_RENAME( CKEDITOR.dtd )

File diff suppressed because it is too large Load Diff

View File

@@ -1,186 +1,186 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
if ( !CKEDITOR.editor ) if ( !CKEDITOR.editor )
{ {
/** /**
* No element is linked to the editor instance. * No element is linked to the editor instance.
* @constant * @constant
* @example * @example
*/ */
CKEDITOR.ELEMENT_MODE_NONE = 0; CKEDITOR.ELEMENT_MODE_NONE = 0;
/** /**
* The element is to be replaced by the editor instance. * The element is to be replaced by the editor instance.
* @constant * @constant
* @example * @example
*/ */
CKEDITOR.ELEMENT_MODE_REPLACE = 1; CKEDITOR.ELEMENT_MODE_REPLACE = 1;
/** /**
* The editor is to be created inside the element. * The editor is to be created inside the element.
* @constant * @constant
* @example * @example
*/ */
CKEDITOR.ELEMENT_MODE_APPENDTO = 2; CKEDITOR.ELEMENT_MODE_APPENDTO = 2;
/** /**
* Creates an editor class instance. This constructor should be rarely * Creates an editor class instance. This constructor should be rarely
* used, in favor of the {@link CKEDITOR} editor creation functions. * used, in favor of the {@link CKEDITOR} editor creation functions.
* @ class Represents an editor instance. * @ class Represents an editor instance.
* @param {Object} instanceConfig Configuration values for this specific * @param {Object} instanceConfig Configuration values for this specific
* instance. * instance.
* @param {CKEDITOR.dom.element} [element] The element linked to this * @param {CKEDITOR.dom.element} [element] The element linked to this
* instance. * instance.
* @param {Number} [mode] The mode in which the element is linked to this * @param {Number} [mode] The mode in which the element is linked to this
* instance. See {@link #elementMode}. * instance. See {@link #elementMode}.
* @param {String} [data] Since 3.3. Initial value for the instance. * @param {String} [data] Since 3.3. Initial value for the instance.
* @augments CKEDITOR.event * @augments CKEDITOR.event
* @example * @example
*/ */
CKEDITOR.editor = function( instanceConfig, element, mode, data ) CKEDITOR.editor = function( instanceConfig, element, mode, data )
{ {
this._ = this._ =
{ {
// Save the config to be processed later by the full core code. // Save the config to be processed later by the full core code.
instanceConfig : instanceConfig, instanceConfig : instanceConfig,
element : element, element : element,
data : data data : data
}; };
/** /**
* The mode in which the {@link #element} is linked to this editor * The mode in which the {@link #element} is linked to this editor
* instance. It can be any of the following values: * instance. It can be any of the following values:
* <ul> * <ul>
* <li>{@link CKEDITOR.ELEMENT_MODE_NONE}: No element is linked to the * <li>{@link CKEDITOR.ELEMENT_MODE_NONE}: No element is linked to the
* editor instance.</li> * editor instance.</li>
* <li>{@link CKEDITOR.ELEMENT_MODE_REPLACE}: The element is to be * <li>{@link CKEDITOR.ELEMENT_MODE_REPLACE}: The element is to be
* replaced by the editor instance.</li> * replaced by the editor instance.</li>
* <li>{@link CKEDITOR.ELEMENT_MODE_APPENDTO}: The editor is to be * <li>{@link CKEDITOR.ELEMENT_MODE_APPENDTO}: The editor is to be
* created inside the element.</li> * created inside the element.</li>
* </ul> * </ul>
* @name CKEDITOR.editor.prototype.elementMode * @name CKEDITOR.editor.prototype.elementMode
* @type Number * @type Number
* @example * @example
* var editor = CKEDITOR.replace( 'editor1' ); * var editor = CKEDITOR.replace( 'editor1' );
* alert( <b>editor.elementMode</b> ); "1" * alert( <b>editor.elementMode</b> ); "1"
*/ */
this.elementMode = mode || CKEDITOR.ELEMENT_MODE_NONE; this.elementMode = mode || CKEDITOR.ELEMENT_MODE_NONE;
// Call the CKEDITOR.event constructor to initialize this instance. // Call the CKEDITOR.event constructor to initialize this instance.
CKEDITOR.event.call( this ); CKEDITOR.event.call( this );
this._init(); this._init();
}; };
/** /**
* Replaces a &lt;textarea&gt; or a DOM element (DIV) with a CKEditor * Replaces a &lt;textarea&gt; or a DOM element (DIV) with a CKEditor
* instance. For textareas, the initial value in the editor will be the * instance. For textareas, the initial value in the editor will be the
* textarea value. For DOM elements, their innerHTML will be used * textarea value. For DOM elements, their innerHTML will be used
* instead. We recommend using TEXTAREA and DIV elements only. Do not use * instead. We recommend using TEXTAREA and DIV elements only. Do not use
* this function directly. Use {@link CKEDITOR.replace} instead. * this function directly. Use {@link CKEDITOR.replace} instead.
* @param {Object|String} elementOrIdOrName The DOM element (textarea), its * @param {Object|String} elementOrIdOrName The DOM element (textarea), its
* ID or name. * ID or name.
* @param {Object} [config] The specific configurations to apply to this * @param {Object} [config] The specific configurations to apply to this
* editor instance. Configurations set here will override global CKEditor * editor instance. Configurations set here will override global CKEditor
* settings. * settings.
* @returns {CKEDITOR.editor} The editor instance created. * @returns {CKEDITOR.editor} The editor instance created.
* @example * @example
*/ */
CKEDITOR.editor.replace = function( elementOrIdOrName, config ) CKEDITOR.editor.replace = function( elementOrIdOrName, config )
{ {
var element = elementOrIdOrName; var element = elementOrIdOrName;
if ( typeof element != 'object' ) if ( typeof element != 'object' )
{ {
// Look for the element by id. We accept any kind of element here. // Look for the element by id. We accept any kind of element here.
element = document.getElementById( elementOrIdOrName ); element = document.getElementById( elementOrIdOrName );
// Elements that should go into head are unacceptable (#6791). // Elements that should go into head are unacceptable (#6791).
if ( element && element.tagName.toLowerCase() in {style:1,script:1,base:1,link:1,meta:1,title:1} ) if ( element && element.tagName.toLowerCase() in {style:1,script:1,base:1,link:1,meta:1,title:1} )
element = null; element = null;
// If not found, look for elements by name. In this case we accept only // If not found, look for elements by name. In this case we accept only
// textareas. // textareas.
if ( !element ) if ( !element )
{ {
var i = 0, var i = 0,
textareasByName = document.getElementsByName( elementOrIdOrName ); textareasByName = document.getElementsByName( elementOrIdOrName );
while ( ( element = textareasByName[ i++ ] ) && element.tagName.toLowerCase() != 'textarea' ) while ( ( element = textareasByName[ i++ ] ) && element.tagName.toLowerCase() != 'textarea' )
{ /*jsl:pass*/ } { /*jsl:pass*/ }
} }
if ( !element ) if ( !element )
throw '[CKEDITOR.editor.replace] The element with id or name "' + elementOrIdOrName + '" was not found.'; throw '[CKEDITOR.editor.replace] The element with id or name "' + elementOrIdOrName + '" was not found.';
} }
// Do not replace the textarea right now, just hide it. The effective // Do not replace the textarea right now, just hide it. The effective
// replacement will be done by the _init function. // replacement will be done by the _init function.
element.style.visibility = 'hidden'; element.style.visibility = 'hidden';
// Create the editor instance. // Create the editor instance.
return new CKEDITOR.editor( config, element, CKEDITOR.ELEMENT_MODE_REPLACE ); return new CKEDITOR.editor( config, element, CKEDITOR.ELEMENT_MODE_REPLACE );
}; };
/** /**
* Creates a new editor instance inside a specific DOM element. Do not use * Creates a new editor instance inside a specific DOM element. Do not use
* this function directly. Use {@link CKEDITOR.appendTo} instead. * this function directly. Use {@link CKEDITOR.appendTo} instead.
* @param {Object|String} elementOrId The DOM element or its ID. * @param {Object|String} elementOrId The DOM element or its ID.
* @param {Object} [config] The specific configurations to apply to this * @param {Object} [config] The specific configurations to apply to this
* editor instance. Configurations set here will override global CKEditor * editor instance. Configurations set here will override global CKEditor
* settings. * settings.
* @param {String} [data] Since 3.3. Initial value for the instance. * @param {String} [data] Since 3.3. Initial value for the instance.
* @returns {CKEDITOR.editor} The editor instance created. * @returns {CKEDITOR.editor} The editor instance created.
* @example * @example
*/ */
CKEDITOR.editor.appendTo = function( elementOrId, config, data ) CKEDITOR.editor.appendTo = function( elementOrId, config, data )
{ {
var element = elementOrId; var element = elementOrId;
if ( typeof element != 'object' ) if ( typeof element != 'object' )
{ {
element = document.getElementById( elementOrId ); element = document.getElementById( elementOrId );
if ( !element ) if ( !element )
throw '[CKEDITOR.editor.appendTo] The element with id "' + elementOrId + '" was not found.'; throw '[CKEDITOR.editor.appendTo] The element with id "' + elementOrId + '" was not found.';
} }
// Create the editor instance. // Create the editor instance.
return new CKEDITOR.editor( config, element, CKEDITOR.ELEMENT_MODE_APPENDTO, data ); return new CKEDITOR.editor( config, element, CKEDITOR.ELEMENT_MODE_APPENDTO, data );
}; };
CKEDITOR.editor.prototype = CKEDITOR.editor.prototype =
{ {
/** /**
* Initializes the editor instance. This function will be overriden by the * Initializes the editor instance. This function will be overriden by the
* full CKEDITOR.editor implementation (editor.js). * full CKEDITOR.editor implementation (editor.js).
* @private * @private
*/ */
_init : function() _init : function()
{ {
var pending = CKEDITOR.editor._pending || ( CKEDITOR.editor._pending = [] ); var pending = CKEDITOR.editor._pending || ( CKEDITOR.editor._pending = [] );
pending.push( this ); pending.push( this );
}, },
// Both fire and fireOnce will always pass this editor instance as the // Both fire and fireOnce will always pass this editor instance as the
// "editor" param in CKEDITOR.event.fire. So, we override it to do that // "editor" param in CKEDITOR.event.fire. So, we override it to do that
// automaticaly. // automaticaly.
/** @ignore */ /** @ignore */
fire : function( eventName, data ) fire : function( eventName, data )
{ {
return CKEDITOR.event.prototype.fire.call( this, eventName, data, this ); return CKEDITOR.event.prototype.fire.call( this, eventName, data, this );
}, },
/** @ignore */ /** @ignore */
fireOnce : function( eventName, data ) fireOnce : function( eventName, data )
{ {
return CKEDITOR.event.prototype.fireOnce.call( this, eventName, data, this ); return CKEDITOR.event.prototype.fireOnce.call( this, eventName, data, this );
} }
}; };
// "Inherit" (copy actually) from CKEDITOR.event. // "Inherit" (copy actually) from CKEDITOR.event.
CKEDITOR.event.implementOn( CKEDITOR.editor.prototype, true ); CKEDITOR.event.implementOn( CKEDITOR.editor.prototype, true );
} }

View File

@@ -1,305 +1,305 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.env} object, which constains * @fileOverview Defines the {@link CKEDITOR.env} object, which constains
* environment and browser information. * environment and browser information.
*/ */
if ( !CKEDITOR.env ) if ( !CKEDITOR.env )
{ {
/** /**
* @namespace Environment and browser information. * @namespace Environment and browser information.
*/ */
CKEDITOR.env = (function() CKEDITOR.env = (function()
{ {
var agent = navigator.userAgent.toLowerCase(); var agent = navigator.userAgent.toLowerCase();
var opera = window.opera; var opera = window.opera;
var env = var env =
/** @lends CKEDITOR.env */ /** @lends CKEDITOR.env */
{ {
/** /**
* Indicates that CKEditor is running on Internet Explorer. * Indicates that CKEditor is running on Internet Explorer.
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.ie ) * if ( CKEDITOR.env.ie )
* alert( "I'm on IE!" ); * alert( "I'm on IE!" );
*/ */
ie : /*@cc_on!@*/false, ie : /*@cc_on!@*/false,
/** /**
* Indicates that CKEditor is running on Opera. * Indicates that CKEditor is running on Opera.
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.opera ) * if ( CKEDITOR.env.opera )
* alert( "I'm on Opera!" ); * alert( "I'm on Opera!" );
*/ */
opera : ( !!opera && opera.version ), opera : ( !!opera && opera.version ),
/** /**
* Indicates that CKEditor is running on a WebKit based browser, like * Indicates that CKEditor is running on a WebKit based browser, like
* Safari. * Safari.
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.webkit ) * if ( CKEDITOR.env.webkit )
* alert( "I'm on WebKit!" ); * alert( "I'm on WebKit!" );
*/ */
webkit : ( agent.indexOf( ' applewebkit/' ) > -1 ), webkit : ( agent.indexOf( ' applewebkit/' ) > -1 ),
/** /**
* Indicates that CKEditor is running on Adobe AIR. * Indicates that CKEditor is running on Adobe AIR.
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.air ) * if ( CKEDITOR.env.air )
* alert( "I'm on AIR!" ); * alert( "I'm on AIR!" );
*/ */
air : ( agent.indexOf( ' adobeair/' ) > -1 ), air : ( agent.indexOf( ' adobeair/' ) > -1 ),
/** /**
* Indicates that CKEditor is running on Macintosh. * Indicates that CKEditor is running on Macintosh.
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.mac ) * if ( CKEDITOR.env.mac )
* alert( "I love apples!" ); * alert( "I love apples!" );
*/ */
mac : ( agent.indexOf( 'macintosh' ) > -1 ), mac : ( agent.indexOf( 'macintosh' ) > -1 ),
/** /**
* Indicates that CKEditor is running on a quirks mode environemnt. * Indicates that CKEditor is running on a quirks mode environemnt.
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.quirks ) * if ( CKEDITOR.env.quirks )
* alert( "Nooooo!" ); * alert( "Nooooo!" );
*/ */
quirks : ( document.compatMode == 'BackCompat' ), quirks : ( document.compatMode == 'BackCompat' ),
/** /**
* Indicates that CKEditor is running on a mobile like environemnt. * Indicates that CKEditor is running on a mobile like environemnt.
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.mobile ) * if ( CKEDITOR.env.mobile )
* alert( "I'm running with CKEditor today!" ); * alert( "I'm running with CKEditor today!" );
*/ */
mobile : ( agent.indexOf( 'mobile' ) > -1 ), mobile : ( agent.indexOf( 'mobile' ) > -1 ),
/** /**
* Indicates that CKEditor is running on Apple iPhone/iPad/iPod devices. * Indicates that CKEditor is running on Apple iPhone/iPad/iPod devices.
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.iOS ) * if ( CKEDITOR.env.iOS )
* alert( "I like little apples!" ); * alert( "I like little apples!" );
*/ */
iOS : /(ipad|iphone|ipod)/.test(agent), iOS : /(ipad|iphone|ipod)/.test(agent),
/** /**
* Indicates that the browser has a custom domain enabled. This has * Indicates that the browser has a custom domain enabled. This has
* been set with "document.domain". * been set with "document.domain".
* @returns {Boolean} "true" if a custom domain is enabled. * @returns {Boolean} "true" if a custom domain is enabled.
* @example * @example
* if ( CKEDITOR.env.isCustomDomain() ) * if ( CKEDITOR.env.isCustomDomain() )
* alert( "I'm in a custom domain!" ); * alert( "I'm in a custom domain!" );
*/ */
isCustomDomain : function() isCustomDomain : function()
{ {
if ( !this.ie ) if ( !this.ie )
return false; return false;
var domain = document.domain, var domain = document.domain,
hostname = window.location.hostname; hostname = window.location.hostname;
return domain != hostname && return domain != hostname &&
domain != ( '[' + hostname + ']' ); // IPv6 IP support (#5434) domain != ( '[' + hostname + ']' ); // IPv6 IP support (#5434)
}, },
/** /**
* Indicates that page is running under an encrypted connection. * Indicates that page is running under an encrypted connection.
* @returns {Boolean} "true" if the page has an encrypted connection. * @returns {Boolean} "true" if the page has an encrypted connection.
* @example * @example
* if ( CKEDITOR.env.secure ) * if ( CKEDITOR.env.secure )
* alert( "I'm in SSL!" ); * alert( "I'm in SSL!" );
*/ */
secure : location.protocol == 'https:' secure : location.protocol == 'https:'
}; };
/** /**
* Indicates that CKEditor is running on a Gecko based browser, like * Indicates that CKEditor is running on a Gecko based browser, like
* Firefox. * Firefox.
* @name CKEDITOR.env.gecko * @name CKEDITOR.env.gecko
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.gecko ) * if ( CKEDITOR.env.gecko )
* alert( "I'm riding a gecko!" ); * alert( "I'm riding a gecko!" );
*/ */
env.gecko = ( navigator.product == 'Gecko' && !env.webkit && !env.opera ); env.gecko = ( navigator.product == 'Gecko' && !env.webkit && !env.opera );
var version = 0; var version = 0;
// Internet Explorer 6.0+ // Internet Explorer 6.0+
if ( env.ie ) if ( env.ie )
{ {
version = parseFloat( agent.match( /msie (\d+)/ )[1] ); version = parseFloat( agent.match( /msie (\d+)/ )[1] );
/** /**
* Indicates that CKEditor is running on Internet Explorer 8. * Indicates that CKEditor is running on Internet Explorer 8.
* @name CKEDITOR.env.ie8 * @name CKEDITOR.env.ie8
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.ie8 ) * if ( CKEDITOR.env.ie8 )
* alert( "I'm on IE8!" ); * alert( "I'm on IE8!" );
*/ */
env.ie8 = !!document.documentMode; env.ie8 = !!document.documentMode;
/** /**
* Indicates that CKEditor is running on Internet Explorer 8 on * Indicates that CKEditor is running on Internet Explorer 8 on
* standards mode. * standards mode.
* @name CKEDITOR.env.ie8Compat * @name CKEDITOR.env.ie8Compat
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.ie8Compat ) * if ( CKEDITOR.env.ie8Compat )
* alert( "Now I'm on IE8, for real!" ); * alert( "Now I'm on IE8, for real!" );
*/ */
env.ie8Compat = document.documentMode == 8; env.ie8Compat = document.documentMode == 8;
/** /**
* Indicates that CKEditor is running on Internet Explorer 9's standards mode. * Indicates that CKEditor is running on Internet Explorer 9's standards mode.
* @name CKEDITOR.env.ie9Compat * @name CKEDITOR.env.ie9Compat
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.ie9Compat ) * if ( CKEDITOR.env.ie9Compat )
* alert( "IE9, the beauty of the web!" ); * alert( "IE9, the beauty of the web!" );
*/ */
env.ie9Compat = document.documentMode == 9; env.ie9Compat = document.documentMode == 9;
/** /**
* Indicates that CKEditor is running on an IE7-like environment, which * Indicates that CKEditor is running on an IE7-like environment, which
* includes IE7 itself and IE8's IE7 document mode. * includes IE7 itself and IE8's IE7 document mode.
* @name CKEDITOR.env.ie7Compat * @name CKEDITOR.env.ie7Compat
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.ie8Compat ) * if ( CKEDITOR.env.ie8Compat )
* alert( "I'm on IE7 or on an IE7 like IE8!" ); * alert( "I'm on IE7 or on an IE7 like IE8!" );
*/ */
env.ie7Compat = ( ( version == 7 && !document.documentMode ) env.ie7Compat = ( ( version == 7 && !document.documentMode )
|| document.documentMode == 7 ); || document.documentMode == 7 );
/** /**
* Indicates that CKEditor is running on an IE6-like environment, which * Indicates that CKEditor is running on an IE6-like environment, which
* includes IE6 itself and IE7 and IE8 quirks mode. * includes IE6 itself and IE7 and IE8 quirks mode.
* @name CKEDITOR.env.ie6Compat * @name CKEDITOR.env.ie6Compat
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.ie6Compat ) * if ( CKEDITOR.env.ie6Compat )
* alert( "I'm on IE6 or quirks mode!" ); * alert( "I'm on IE6 or quirks mode!" );
*/ */
env.ie6Compat = ( version < 7 || env.quirks ); env.ie6Compat = ( version < 7 || env.quirks );
} }
// Gecko. // Gecko.
if ( env.gecko ) if ( env.gecko )
{ {
var geckoRelease = agent.match( /rv:([\d\.]+)/ ); var geckoRelease = agent.match( /rv:([\d\.]+)/ );
if ( geckoRelease ) if ( geckoRelease )
{ {
geckoRelease = geckoRelease[1].split( '.' ); geckoRelease = geckoRelease[1].split( '.' );
version = geckoRelease[0] * 10000 + ( geckoRelease[1] || 0 ) * 100 + ( geckoRelease[2] || 0 ) * 1; version = geckoRelease[0] * 10000 + ( geckoRelease[1] || 0 ) * 100 + ( geckoRelease[2] || 0 ) * 1;
} }
} }
// Opera 9.50+ // Opera 9.50+
if ( env.opera ) if ( env.opera )
version = parseFloat( opera.version() ); version = parseFloat( opera.version() );
// Adobe AIR 1.0+ // Adobe AIR 1.0+
// Checked before Safari because AIR have the WebKit rich text editor // Checked before Safari because AIR have the WebKit rich text editor
// features from Safari 3.0.4, but the version reported is 420. // features from Safari 3.0.4, but the version reported is 420.
if ( env.air ) if ( env.air )
version = parseFloat( agent.match( / adobeair\/(\d+)/ )[1] ); version = parseFloat( agent.match( / adobeair\/(\d+)/ )[1] );
// WebKit 522+ (Safari 3+) // WebKit 522+ (Safari 3+)
if ( env.webkit ) if ( env.webkit )
version = parseFloat( agent.match( / applewebkit\/(\d+)/ )[1] ); version = parseFloat( agent.match( / applewebkit\/(\d+)/ )[1] );
/** /**
* Contains the browser version.<br /> * Contains the browser version.<br />
* <br /> * <br />
* For gecko based browsers (like Firefox) it contains the revision * For gecko based browsers (like Firefox) it contains the revision
* number with first three parts concatenated with a padding zero * number with first three parts concatenated with a padding zero
* (e.g. for revision 1.9.0.2 we have 10900).<br /> * (e.g. for revision 1.9.0.2 we have 10900).<br />
* <br /> * <br />
* For webkit based browser (like Safari and Chrome) it contains the * For webkit based browser (like Safari and Chrome) it contains the
* WebKit build version (e.g. 522). * WebKit build version (e.g. 522).
* @name CKEDITOR.env.version * @name CKEDITOR.env.version
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.ie && <b>CKEDITOR.env.version</b> <= 6 ) * if ( CKEDITOR.env.ie && <b>CKEDITOR.env.version</b> <= 6 )
* alert( "Ouch!" ); * alert( "Ouch!" );
*/ */
env.version = version; env.version = version;
/** /**
* Indicates that CKEditor is running on a compatible browser. * Indicates that CKEditor is running on a compatible browser.
* @name CKEDITOR.env.isCompatible * @name CKEDITOR.env.isCompatible
* @type Boolean * @type Boolean
* @example * @example
* if ( CKEDITOR.env.isCompatible ) * if ( CKEDITOR.env.isCompatible )
* alert( "Your browser is pretty cool!" ); * alert( "Your browser is pretty cool!" );
*/ */
env.isCompatible = env.isCompatible =
// White list of mobile devices that supports. // White list of mobile devices that supports.
env.iOS && version >= 534 || env.iOS && version >= 534 ||
!env.mobile && ( !env.mobile && (
( env.ie && version >= 6 ) || ( env.ie && version >= 6 ) ||
( env.gecko && version >= 10801 ) || ( env.gecko && version >= 10801 ) ||
( env.opera && version >= 9.5 ) || ( env.opera && version >= 9.5 ) ||
( env.air && version >= 1 ) || ( env.air && version >= 1 ) ||
( env.webkit && version >= 522 ) || ( env.webkit && version >= 522 ) ||
false ); false );
/** /**
* The CSS class to be appended on the main UI containers, making it * The CSS class to be appended on the main UI containers, making it
* easy to apply browser specific styles to it. * easy to apply browser specific styles to it.
* @name CKEDITOR.env.cssClass * @name CKEDITOR.env.cssClass
* @type String * @type String
* @example * @example
* myDiv.className = CKEDITOR.env.cssClass; * myDiv.className = CKEDITOR.env.cssClass;
*/ */
env.cssClass = env.cssClass =
'cke_browser_' + ( 'cke_browser_' + (
env.ie ? 'ie' : env.ie ? 'ie' :
env.gecko ? 'gecko' : env.gecko ? 'gecko' :
env.opera ? 'opera' : env.opera ? 'opera' :
env.webkit ? 'webkit' : env.webkit ? 'webkit' :
'unknown' ); 'unknown' );
if ( env.quirks ) if ( env.quirks )
env.cssClass += ' cke_browser_quirks'; env.cssClass += ' cke_browser_quirks';
if ( env.ie ) if ( env.ie )
{ {
env.cssClass += ' cke_browser_ie' + ( env.cssClass += ' cke_browser_ie' + (
env.version < 7 ? '6' : env.version < 7 ? '6' :
env.version >= 8 ? document.documentMode: env.version >= 8 ? document.documentMode:
'7' ); '7' );
if ( env.quirks ) if ( env.quirks )
env.cssClass += ' cke_browser_iequirks'; env.cssClass += ' cke_browser_iequirks';
} }
if ( env.gecko && version < 10900 ) if ( env.gecko && version < 10900 )
env.cssClass += ' cke_browser_gecko18'; env.cssClass += ' cke_browser_gecko18';
if ( env.air ) if ( env.air )
env.cssClass += ' cke_browser_air'; env.cssClass += ' cke_browser_air';
return env; return env;
})(); })();
} }
// PACKAGER_RENAME( CKEDITOR.env ) // PACKAGER_RENAME( CKEDITOR.env )
// PACKAGER_RENAME( CKEDITOR.env.ie ) // PACKAGER_RENAME( CKEDITOR.env.ie )

View File

@@ -1,342 +1,342 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.event} class, which serves as the * @fileOverview Defines the {@link CKEDITOR.event} class, which serves as the
* base for classes and objects that require event handling features. * base for classes and objects that require event handling features.
*/ */
if ( !CKEDITOR.event ) if ( !CKEDITOR.event )
{ {
/** /**
* Creates an event class instance. This constructor is rearely used, being * Creates an event class instance. This constructor is rearely used, being
* the {@link #.implementOn} function used in class prototypes directly * the {@link #.implementOn} function used in class prototypes directly
* instead. * instead.
* @class This is a base class for classes and objects that require event * @class This is a base class for classes and objects that require event
* handling features.<br /> * handling features.<br />
* <br /> * <br />
* Do not confuse this class with {@link CKEDITOR.dom.event} which is * Do not confuse this class with {@link CKEDITOR.dom.event} which is
* instead used for DOM events. The CKEDITOR.event class implements the * instead used for DOM events. The CKEDITOR.event class implements the
* internal event system used by the CKEditor to fire API related events. * internal event system used by the CKEditor to fire API related events.
* @example * @example
*/ */
CKEDITOR.event = function() CKEDITOR.event = function()
{}; {};
/** /**
* Implements the {@link CKEDITOR.event} features in an object. * Implements the {@link CKEDITOR.event} features in an object.
* @param {Object} targetObject The object into which implement the features. * @param {Object} targetObject The object into which implement the features.
* @example * @example
* var myObject = { message : 'Example' }; * var myObject = { message : 'Example' };
* <b>CKEDITOR.event.implementOn( myObject }</b>; * <b>CKEDITOR.event.implementOn( myObject }</b>;
* myObject.on( 'testEvent', function() * myObject.on( 'testEvent', function()
* { * {
* alert( this.message ); // "Example" * alert( this.message ); // "Example"
* }); * });
* myObject.fire( 'testEvent' ); * myObject.fire( 'testEvent' );
*/ */
CKEDITOR.event.implementOn = function( targetObject ) CKEDITOR.event.implementOn = function( targetObject )
{ {
var eventProto = CKEDITOR.event.prototype; var eventProto = CKEDITOR.event.prototype;
for ( var prop in eventProto ) for ( var prop in eventProto )
{ {
if ( targetObject[ prop ] == undefined ) if ( targetObject[ prop ] == undefined )
targetObject[ prop ] = eventProto[ prop ]; targetObject[ prop ] = eventProto[ prop ];
} }
}; };
CKEDITOR.event.prototype = (function() CKEDITOR.event.prototype = (function()
{ {
// Returns the private events object for a given object. // Returns the private events object for a given object.
var getPrivate = function( obj ) var getPrivate = function( obj )
{ {
var _ = ( obj.getPrivate && obj.getPrivate() ) || obj._ || ( obj._ = {} ); var _ = ( obj.getPrivate && obj.getPrivate() ) || obj._ || ( obj._ = {} );
return _.events || ( _.events = {} ); return _.events || ( _.events = {} );
}; };
var eventEntry = function( eventName ) var eventEntry = function( eventName )
{ {
this.name = eventName; this.name = eventName;
this.listeners = []; this.listeners = [];
}; };
eventEntry.prototype = eventEntry.prototype =
{ {
// Get the listener index for a specified function. // Get the listener index for a specified function.
// Returns -1 if not found. // Returns -1 if not found.
getListenerIndex : function( listenerFunction ) getListenerIndex : function( listenerFunction )
{ {
for ( var i = 0, listeners = this.listeners ; i < listeners.length ; i++ ) for ( var i = 0, listeners = this.listeners ; i < listeners.length ; i++ )
{ {
if ( listeners[i].fn == listenerFunction ) if ( listeners[i].fn == listenerFunction )
return i; return i;
} }
return -1; return -1;
} }
}; };
return /** @lends CKEDITOR.event.prototype */ { return /** @lends CKEDITOR.event.prototype */ {
/** /**
* Registers a listener to a specific event in the current object. * Registers a listener to a specific event in the current object.
* @param {String} eventName The event name to which listen. * @param {String} eventName The event name to which listen.
* @param {Function} listenerFunction The function listening to the * @param {Function} listenerFunction The function listening to the
* event. A single {@link CKEDITOR.eventInfo} object instanced * event. A single {@link CKEDITOR.eventInfo} object instanced
* is passed to this function containing all the event data. * is passed to this function containing all the event data.
* @param {Object} [scopeObj] The object used to scope the listener * @param {Object} [scopeObj] The object used to scope the listener
* call (the this object. If omitted, the current object is used. * call (the this object. If omitted, the current object is used.
* @param {Object} [listenerData] Data to be sent as the * @param {Object} [listenerData] Data to be sent as the
* {@link CKEDITOR.eventInfo#listenerData} when calling the * {@link CKEDITOR.eventInfo#listenerData} when calling the
* listener. * listener.
* @param {Number} [priority] The listener priority. Lower priority * @param {Number} [priority] The listener priority. Lower priority
* listeners are called first. Listeners with the same priority * listeners are called first. Listeners with the same priority
* value are called in registration order. Defaults to 10. * value are called in registration order. Defaults to 10.
* @example * @example
* someObject.on( 'someEvent', function() * someObject.on( 'someEvent', function()
* { * {
* alert( this == someObject ); // "true" * alert( this == someObject ); // "true"
* }); * });
* @example * @example
* someObject.on( 'someEvent', function() * someObject.on( 'someEvent', function()
* { * {
* alert( this == anotherObject ); // "true" * alert( this == anotherObject ); // "true"
* } * }
* , anotherObject ); * , anotherObject );
* @example * @example
* someObject.on( 'someEvent', function( event ) * someObject.on( 'someEvent', function( event )
* { * {
* alert( event.listenerData ); // "Example" * alert( event.listenerData ); // "Example"
* } * }
* , null, 'Example' ); * , null, 'Example' );
* @example * @example
* someObject.on( 'someEvent', function() { ... } ); // 2nd called * someObject.on( 'someEvent', function() { ... } ); // 2nd called
* someObject.on( 'someEvent', function() { ... }, null, null, 100 ); // 3rd called * someObject.on( 'someEvent', function() { ... }, null, null, 100 ); // 3rd called
* someObject.on( 'someEvent', function() { ... }, null, null, 1 ); // 1st called * someObject.on( 'someEvent', function() { ... }, null, null, 1 ); // 1st called
*/ */
on : function( eventName, listenerFunction, scopeObj, listenerData, priority ) on : function( eventName, listenerFunction, scopeObj, listenerData, priority )
{ {
// Get the event entry (create it if needed). // Get the event entry (create it if needed).
var events = getPrivate( this ), var events = getPrivate( this ),
event = events[ eventName ] || ( events[ eventName ] = new eventEntry( eventName ) ); event = events[ eventName ] || ( events[ eventName ] = new eventEntry( eventName ) );
if ( event.getListenerIndex( listenerFunction ) < 0 ) if ( event.getListenerIndex( listenerFunction ) < 0 )
{ {
// Get the listeners. // Get the listeners.
var listeners = event.listeners; var listeners = event.listeners;
// Fill the scope. // Fill the scope.
if ( !scopeObj ) if ( !scopeObj )
scopeObj = this; scopeObj = this;
// Default the priority, if needed. // Default the priority, if needed.
if ( isNaN( priority ) ) if ( isNaN( priority ) )
priority = 10; priority = 10;
var me = this; var me = this;
// Create the function to be fired for this listener. // Create the function to be fired for this listener.
var listenerFirer = function( editor, publisherData, stopFn, cancelFn ) var listenerFirer = function( editor, publisherData, stopFn, cancelFn )
{ {
var ev = var ev =
{ {
name : eventName, name : eventName,
sender : this, sender : this,
editor : editor, editor : editor,
data : publisherData, data : publisherData,
listenerData : listenerData, listenerData : listenerData,
stop : stopFn, stop : stopFn,
cancel : cancelFn, cancel : cancelFn,
removeListener : function() removeListener : function()
{ {
me.removeListener( eventName, listenerFunction ); me.removeListener( eventName, listenerFunction );
} }
}; };
listenerFunction.call( scopeObj, ev ); listenerFunction.call( scopeObj, ev );
return ev.data; return ev.data;
}; };
listenerFirer.fn = listenerFunction; listenerFirer.fn = listenerFunction;
listenerFirer.priority = priority; listenerFirer.priority = priority;
// Search for the right position for this new listener, based on its // Search for the right position for this new listener, based on its
// priority. // priority.
for ( var i = listeners.length - 1 ; i >= 0 ; i-- ) for ( var i = listeners.length - 1 ; i >= 0 ; i-- )
{ {
// Find the item which should be before the new one. // Find the item which should be before the new one.
if ( listeners[ i ].priority <= priority ) if ( listeners[ i ].priority <= priority )
{ {
// Insert the listener in the array. // Insert the listener in the array.
listeners.splice( i + 1, 0, listenerFirer ); listeners.splice( i + 1, 0, listenerFirer );
return; return;
} }
} }
// If no position has been found (or zero length), put it in // If no position has been found (or zero length), put it in
// the front of list. // the front of list.
listeners.unshift( listenerFirer ); listeners.unshift( listenerFirer );
} }
}, },
/** /**
* Fires an specific event in the object. All registered listeners are * Fires an specific event in the object. All registered listeners are
* called at this point. * called at this point.
* @function * @function
* @param {String} eventName The event name to fire. * @param {String} eventName The event name to fire.
* @param {Object} [data] Data to be sent as the * @param {Object} [data] Data to be sent as the
* {@link CKEDITOR.eventInfo#data} when calling the * {@link CKEDITOR.eventInfo#data} when calling the
* listeners. * listeners.
* @param {CKEDITOR.editor} [editor] The editor instance to send as the * @param {CKEDITOR.editor} [editor] The editor instance to send as the
* {@link CKEDITOR.eventInfo#editor} when calling the * {@link CKEDITOR.eventInfo#editor} when calling the
* listener. * listener.
* @returns {Boolean|Object} A booloan indicating that the event is to be * @returns {Boolean|Object} A booloan indicating that the event is to be
* canceled, or data returned by one of the listeners. * canceled, or data returned by one of the listeners.
* @example * @example
* someObject.on( 'someEvent', function() { ... } ); * someObject.on( 'someEvent', function() { ... } );
* someObject.on( 'someEvent', function() { ... } ); * someObject.on( 'someEvent', function() { ... } );
* <b>someObject.fire( 'someEvent' )</b>; // both listeners are called * <b>someObject.fire( 'someEvent' )</b>; // both listeners are called
* @example * @example
* someObject.on( 'someEvent', function( event ) * someObject.on( 'someEvent', function( event )
* { * {
* alert( event.data ); // "Example" * alert( event.data ); // "Example"
* }); * });
* <b>someObject.fire( 'someEvent', 'Example' )</b>; * <b>someObject.fire( 'someEvent', 'Example' )</b>;
*/ */
fire : (function() fire : (function()
{ {
// Create the function that marks the event as stopped. // Create the function that marks the event as stopped.
var stopped = false; var stopped = false;
var stopEvent = function() var stopEvent = function()
{ {
stopped = true; stopped = true;
}; };
// Create the function that marks the event as canceled. // Create the function that marks the event as canceled.
var canceled = false; var canceled = false;
var cancelEvent = function() var cancelEvent = function()
{ {
canceled = true; canceled = true;
}; };
return function( eventName, data, editor ) return function( eventName, data, editor )
{ {
// Get the event entry. // Get the event entry.
var event = getPrivate( this )[ eventName ]; var event = getPrivate( this )[ eventName ];
// Save the previous stopped and cancelled states. We may // Save the previous stopped and cancelled states. We may
// be nesting fire() calls. // be nesting fire() calls.
var previousStopped = stopped, var previousStopped = stopped,
previousCancelled = canceled; previousCancelled = canceled;
// Reset the stopped and canceled flags. // Reset the stopped and canceled flags.
stopped = canceled = false; stopped = canceled = false;
if ( event ) if ( event )
{ {
var listeners = event.listeners; var listeners = event.listeners;
if ( listeners.length ) if ( listeners.length )
{ {
// As some listeners may remove themselves from the // As some listeners may remove themselves from the
// event, the original array length is dinamic. So, // event, the original array length is dinamic. So,
// let's make a copy of all listeners, so we are // let's make a copy of all listeners, so we are
// sure we'll call all of them. // sure we'll call all of them.
listeners = listeners.slice( 0 ); listeners = listeners.slice( 0 );
// Loop through all listeners. // Loop through all listeners.
for ( var i = 0 ; i < listeners.length ; i++ ) for ( var i = 0 ; i < listeners.length ; i++ )
{ {
// Call the listener, passing the event data. // Call the listener, passing the event data.
var retData = listeners[i].call( this, editor, data, stopEvent, cancelEvent ); var retData = listeners[i].call( this, editor, data, stopEvent, cancelEvent );
if ( typeof retData != 'undefined' ) if ( typeof retData != 'undefined' )
data = retData; data = retData;
// No further calls is stopped or canceled. // No further calls is stopped or canceled.
if ( stopped || canceled ) if ( stopped || canceled )
break; break;
} }
} }
} }
var ret = canceled || ( typeof data == 'undefined' ? false : data ); var ret = canceled || ( typeof data == 'undefined' ? false : data );
// Restore the previous stopped and canceled states. // Restore the previous stopped and canceled states.
stopped = previousStopped; stopped = previousStopped;
canceled = previousCancelled; canceled = previousCancelled;
return ret; return ret;
}; };
})(), })(),
/** /**
* Fires an specific event in the object, releasing all listeners * Fires an specific event in the object, releasing all listeners
* registered to that event. The same listeners are not called again on * registered to that event. The same listeners are not called again on
* successive calls of it or of {@link #fire}. * successive calls of it or of {@link #fire}.
* @param {String} eventName The event name to fire. * @param {String} eventName The event name to fire.
* @param {Object} [data] Data to be sent as the * @param {Object} [data] Data to be sent as the
* {@link CKEDITOR.eventInfo#data} when calling the * {@link CKEDITOR.eventInfo#data} when calling the
* listeners. * listeners.
* @param {CKEDITOR.editor} [editor] The editor instance to send as the * @param {CKEDITOR.editor} [editor] The editor instance to send as the
* {@link CKEDITOR.eventInfo#editor} when calling the * {@link CKEDITOR.eventInfo#editor} when calling the
* listener. * listener.
* @returns {Boolean|Object} A booloan indicating that the event is to be * @returns {Boolean|Object} A booloan indicating that the event is to be
* canceled, or data returned by one of the listeners. * canceled, or data returned by one of the listeners.
* @example * @example
* someObject.on( 'someEvent', function() { ... } ); * someObject.on( 'someEvent', function() { ... } );
* someObject.fire( 'someEvent' ); // above listener called * someObject.fire( 'someEvent' ); // above listener called
* <b>someObject.fireOnce( 'someEvent' )</b>; // above listener called * <b>someObject.fireOnce( 'someEvent' )</b>; // above listener called
* someObject.fire( 'someEvent' ); // no listeners called * someObject.fire( 'someEvent' ); // no listeners called
*/ */
fireOnce : function( eventName, data, editor ) fireOnce : function( eventName, data, editor )
{ {
var ret = this.fire( eventName, data, editor ); var ret = this.fire( eventName, data, editor );
delete getPrivate( this )[ eventName ]; delete getPrivate( this )[ eventName ];
return ret; return ret;
}, },
/** /**
* Unregisters a listener function from being called at the specified * Unregisters a listener function from being called at the specified
* event. No errors are thrown if the listener has not been * event. No errors are thrown if the listener has not been
* registered previously. * registered previously.
* @param {String} eventName The event name. * @param {String} eventName The event name.
* @param {Function} listenerFunction The listener function to unregister. * @param {Function} listenerFunction The listener function to unregister.
* @example * @example
* var myListener = function() { ... }; * var myListener = function() { ... };
* someObject.on( 'someEvent', myListener ); * someObject.on( 'someEvent', myListener );
* someObject.fire( 'someEvent' ); // myListener called * someObject.fire( 'someEvent' ); // myListener called
* <b>someObject.removeListener( 'someEvent', myListener )</b>; * <b>someObject.removeListener( 'someEvent', myListener )</b>;
* someObject.fire( 'someEvent' ); // myListener not called * someObject.fire( 'someEvent' ); // myListener not called
*/ */
removeListener : function( eventName, listenerFunction ) removeListener : function( eventName, listenerFunction )
{ {
// Get the event entry. // Get the event entry.
var event = getPrivate( this )[ eventName ]; var event = getPrivate( this )[ eventName ];
if ( event ) if ( event )
{ {
var index = event.getListenerIndex( listenerFunction ); var index = event.getListenerIndex( listenerFunction );
if ( index >= 0 ) if ( index >= 0 )
event.listeners.splice( index, 1 ); event.listeners.splice( index, 1 );
} }
}, },
/** /**
* Checks if there is any listener registered to a given event. * Checks if there is any listener registered to a given event.
* @param {String} eventName The event name. * @param {String} eventName The event name.
* @example * @example
* var myListener = function() { ... }; * var myListener = function() { ... };
* someObject.on( 'someEvent', myListener ); * someObject.on( 'someEvent', myListener );
* alert( someObject.<b>hasListeners( 'someEvent' )</b> ); // "true" * alert( someObject.<b>hasListeners( 'someEvent' )</b> ); // "true"
* alert( someObject.<b>hasListeners( 'noEvent' )</b> ); // "false" * alert( someObject.<b>hasListeners( 'noEvent' )</b> ); // "false"
*/ */
hasListeners : function( eventName ) hasListeners : function( eventName )
{ {
var event = getPrivate( this )[ eventName ]; var event = getPrivate( this )[ eventName ];
return ( event && event.listeners.length > 0 ) ; return ( event && event.listeners.length > 0 ) ;
} }
}; };
})(); })();
} }

View File

@@ -1,132 +1,132 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the "virtual" {@link CKEDITOR.eventInfo} class, which * @fileOverview Defines the "virtual" {@link CKEDITOR.eventInfo} class, which
* contains the defintions of the event object passed to event listeners. * contains the defintions of the event object passed to event listeners.
* This file is for documentation purposes only. * This file is for documentation purposes only.
*/ */
/** /**
* (Virtual Class) Do not call this constructor. This class is not really part * (Virtual Class) Do not call this constructor. This class is not really part
* of the API. * of the API.
* @class Virtual class that illustrates the features of the event object to be * @class Virtual class that illustrates the features of the event object to be
* passed to event listeners by a {@link CKEDITOR.event} based object. * passed to event listeners by a {@link CKEDITOR.event} based object.
* @name CKEDITOR.eventInfo * @name CKEDITOR.eventInfo
* @example * @example
* // Do not do this. * // Do not do this.
* var myEvent = new CKEDITOR.eventInfo(); // Error: CKEDITOR.eventInfo is undefined * var myEvent = new CKEDITOR.eventInfo(); // Error: CKEDITOR.eventInfo is undefined
*/ */
/** /**
* The event name. * The event name.
* @name CKEDITOR.eventInfo.prototype.name * @name CKEDITOR.eventInfo.prototype.name
* @field * @field
* @type String * @type String
* @example * @example
* someObject.on( 'someEvent', function( event ) * someObject.on( 'someEvent', function( event )
* { * {
* alert( <b>event.name</b> ); // "someEvent" * alert( <b>event.name</b> ); // "someEvent"
* }); * });
* someObject.fire( 'someEvent' ); * someObject.fire( 'someEvent' );
*/ */
/** /**
* The object that publishes (sends) the event. * The object that publishes (sends) the event.
* @name CKEDITOR.eventInfo.prototype.sender * @name CKEDITOR.eventInfo.prototype.sender
* @field * @field
* @type Object * @type Object
* @example * @example
* someObject.on( 'someEvent', function( event ) * someObject.on( 'someEvent', function( event )
* { * {
* alert( <b>event.sender</b> == someObject ); // "true" * alert( <b>event.sender</b> == someObject ); // "true"
* }); * });
* someObject.fire( 'someEvent' ); * someObject.fire( 'someEvent' );
*/ */
/** /**
* The editor instance that holds the sender. May be the same as sender. May be * The editor instance that holds the sender. May be the same as sender. May be
* null if the sender is not part of an editor instance, like a component * null if the sender is not part of an editor instance, like a component
* running in standalone mode. * running in standalone mode.
* @name CKEDITOR.eventInfo.prototype.editor * @name CKEDITOR.eventInfo.prototype.editor
* @field * @field
* @type CKEDITOR.editor * @type CKEDITOR.editor
* @example * @example
* myButton.on( 'someEvent', function( event ) * myButton.on( 'someEvent', function( event )
* { * {
* alert( <b>event.editor</b> == myEditor ); // "true" * alert( <b>event.editor</b> == myEditor ); // "true"
* }); * });
* myButton.fire( 'someEvent', null, <b>myEditor</b> ); * myButton.fire( 'someEvent', null, <b>myEditor</b> );
*/ */
/** /**
* Any kind of additional data. Its format and usage is event dependent. * Any kind of additional data. Its format and usage is event dependent.
* @name CKEDITOR.eventInfo.prototype.data * @name CKEDITOR.eventInfo.prototype.data
* @field * @field
* @type Object * @type Object
* @example * @example
* someObject.on( 'someEvent', function( event ) * someObject.on( 'someEvent', function( event )
* { * {
* alert( <b>event.data</b> ); // "Example" * alert( <b>event.data</b> ); // "Example"
* }); * });
* someObject.fire( 'someEvent', <b>'Example'</b> ); * someObject.fire( 'someEvent', <b>'Example'</b> );
*/ */
/** /**
* Any extra data appended during the listener registration. * Any extra data appended during the listener registration.
* @name CKEDITOR.eventInfo.prototype.listenerData * @name CKEDITOR.eventInfo.prototype.listenerData
* @field * @field
* @type Object * @type Object
* @example * @example
* someObject.on( 'someEvent', function( event ) * someObject.on( 'someEvent', function( event )
* { * {
* alert( <b>event.listenerData</b> ); // "Example" * alert( <b>event.listenerData</b> ); // "Example"
* } * }
* , null, <b>'Example'</b> ); * , null, <b>'Example'</b> );
*/ */
/** /**
* Indicates that no further listeners are to be called. * Indicates that no further listeners are to be called.
* @name CKEDITOR.eventInfo.prototype.stop * @name CKEDITOR.eventInfo.prototype.stop
* @function * @function
* @example * @example
* someObject.on( 'someEvent', function( event ) * someObject.on( 'someEvent', function( event )
* { * {
* <b>event.stop()</b>; * <b>event.stop()</b>;
* }); * });
* someObject.on( 'someEvent', function( event ) * someObject.on( 'someEvent', function( event )
* { * {
* // This one will not be called. * // This one will not be called.
* }); * });
* alert( someObject.fire( 'someEvent' ) ); // "false" * alert( someObject.fire( 'someEvent' ) ); // "false"
*/ */
/** /**
* Indicates that the event is to be cancelled (if cancelable). * Indicates that the event is to be cancelled (if cancelable).
* @name CKEDITOR.eventInfo.prototype.cancel * @name CKEDITOR.eventInfo.prototype.cancel
* @function * @function
* @example * @example
* someObject.on( 'someEvent', function( event ) * someObject.on( 'someEvent', function( event )
* { * {
* <b>event.cancel()</b>; * <b>event.cancel()</b>;
* }); * });
* someObject.on( 'someEvent', function( event ) * someObject.on( 'someEvent', function( event )
* { * {
* // This one will not be called. * // This one will not be called.
* }); * });
* alert( someObject.fire( 'someEvent' ) ); // "true" * alert( someObject.fire( 'someEvent' ) ); // "true"
*/ */
/** /**
* Removes the current listener. * Removes the current listener.
* @name CKEDITOR.eventInfo.prototype.removeListener * @name CKEDITOR.eventInfo.prototype.removeListener
* @function * @function
* @example * @example
* someObject.on( 'someEvent', function( event ) * someObject.on( 'someEvent', function( event )
* { * {
* <b>event.removeListener()</b>; * <b>event.removeListener()</b>;
* // Now this function won't be called again by 'someEvent' * // Now this function won't be called again by 'someEvent'
* }); * });
*/ */

View File

@@ -1,152 +1,152 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.focusManager} class, which is used * @fileOverview Defines the {@link CKEDITOR.focusManager} class, which is used
* to handle the focus on editor instances.. * to handle the focus on editor instances..
*/ */
/** /**
* Creates a focusManager class instance. * Creates a focusManager class instance.
* @class Manages the focus activity in an editor instance. This class is to be * @class Manages the focus activity in an editor instance. This class is to be
* used mainly by UI elements coders when adding interface elements that need * used mainly by UI elements coders when adding interface elements that need
* to set the focus state of the editor. * to set the focus state of the editor.
* @param {CKEDITOR.editor} editor The editor instance. * @param {CKEDITOR.editor} editor The editor instance.
* @example * @example
* var focusManager = <b>new CKEDITOR.focusManager( editor )</b>; * var focusManager = <b>new CKEDITOR.focusManager( editor )</b>;
* focusManager.focus(); * focusManager.focus();
*/ */
CKEDITOR.focusManager = function( editor ) CKEDITOR.focusManager = function( editor )
{ {
if ( editor.focusManager ) if ( editor.focusManager )
return editor.focusManager; return editor.focusManager;
/** /**
* Indicates that the editor instance has focus. * Indicates that the editor instance has focus.
* @type Boolean * @type Boolean
* @example * @example
* alert( CKEDITOR.instances.editor1.focusManager.hasFocus ); // e.g "true" * alert( CKEDITOR.instances.editor1.focusManager.hasFocus ); // e.g "true"
*/ */
this.hasFocus = false; this.hasFocus = false;
/** /**
* Object used to hold private stuff. * Object used to hold private stuff.
* @private * @private
*/ */
this._ = this._ =
{ {
editor : editor editor : editor
}; };
return this; return this;
}; };
CKEDITOR.focusManager.prototype = CKEDITOR.focusManager.prototype =
{ {
/** /**
* Used to indicate that the editor instance has the focus.<br /> * Used to indicate that the editor instance has the focus.<br />
* <br /> * <br />
* Note that this function will not explicitelly set the focus in the * Note that this function will not explicitelly set the focus in the
* editor (for example, making the caret blinking on it). Use * editor (for example, making the caret blinking on it). Use
* {@link CKEDITOR.editor#focus} for it instead. * {@link CKEDITOR.editor#focus} for it instead.
* @example * @example
* var editor = CKEDITOR.instances.editor1; * var editor = CKEDITOR.instances.editor1;
* <b>editor.focusManager.focus()</b>; * <b>editor.focusManager.focus()</b>;
*/ */
focus : function() focus : function()
{ {
if ( this._.timer ) if ( this._.timer )
clearTimeout( this._.timer ); clearTimeout( this._.timer );
if ( !this.hasFocus ) if ( !this.hasFocus )
{ {
// If another editor has the current focus, we first "blur" it. In // If another editor has the current focus, we first "blur" it. In
// this way the events happen in a more logical sequence, like: // this way the events happen in a more logical sequence, like:
// "focus 1" > "blur 1" > "focus 2" // "focus 1" > "blur 1" > "focus 2"
// ... instead of: // ... instead of:
// "focus 1" > "focus 2" > "blur 1" // "focus 1" > "focus 2" > "blur 1"
if ( CKEDITOR.currentInstance ) if ( CKEDITOR.currentInstance )
CKEDITOR.currentInstance.focusManager.forceBlur(); CKEDITOR.currentInstance.focusManager.forceBlur();
var editor = this._.editor; var editor = this._.editor;
editor.container.getChild( 1 ).addClass( 'cke_focus' ); editor.container.getChild( 1 ).addClass( 'cke_focus' );
this.hasFocus = true; this.hasFocus = true;
editor.fire( 'focus' ); editor.fire( 'focus' );
} }
}, },
/** /**
* Used to indicate that the editor instance has lost the focus.<br /> * Used to indicate that the editor instance has lost the focus.<br />
* <br /> * <br />
* Note that this functions acts asynchronously with a delay of 100ms to * Note that this functions acts asynchronously with a delay of 100ms to
* avoid subsequent blur/focus effects. If you want the "blur" to happen * avoid subsequent blur/focus effects. If you want the "blur" to happen
* immediately, use the {@link #forceBlur} function instead. * immediately, use the {@link #forceBlur} function instead.
* @example * @example
* var editor = CKEDITOR.instances.editor1; * var editor = CKEDITOR.instances.editor1;
* <b>editor.focusManager.blur()</b>; * <b>editor.focusManager.blur()</b>;
*/ */
blur : function() blur : function()
{ {
var focusManager = this; var focusManager = this;
if ( focusManager._.timer ) if ( focusManager._.timer )
clearTimeout( focusManager._.timer ); clearTimeout( focusManager._.timer );
focusManager._.timer = setTimeout( focusManager._.timer = setTimeout(
function() function()
{ {
delete focusManager._.timer; delete focusManager._.timer;
focusManager.forceBlur(); focusManager.forceBlur();
} }
, 100 ); , 100 );
}, },
/** /**
* Used to indicate that the editor instance has lost the focus. Unlike * Used to indicate that the editor instance has lost the focus. Unlike
* {@link #blur}, this function is synchronous, marking the instance as * {@link #blur}, this function is synchronous, marking the instance as
* "blured" immediately. * "blured" immediately.
* @example * @example
* var editor = CKEDITOR.instances.editor1; * var editor = CKEDITOR.instances.editor1;
* <b>editor.focusManager.forceBlur()</b>; * <b>editor.focusManager.forceBlur()</b>;
*/ */
forceBlur : function() forceBlur : function()
{ {
if ( this.hasFocus ) if ( this.hasFocus )
{ {
var editor = this._.editor; var editor = this._.editor;
editor.container.getChild( 1 ).removeClass( 'cke_focus' ); editor.container.getChild( 1 ).removeClass( 'cke_focus' );
this.hasFocus = false; this.hasFocus = false;
editor.fire( 'blur' ); editor.fire( 'blur' );
} }
} }
}; };
/** /**
* Fired when the editor instance receives the input focus. * Fired when the editor instance receives the input focus.
* @name CKEDITOR.editor#focus * @name CKEDITOR.editor#focus
* @event * @event
* @param {CKEDITOR.editor} editor The editor instance. * @param {CKEDITOR.editor} editor The editor instance.
* @example * @example
* editor.on( 'focus', function( e ) * editor.on( 'focus', function( e )
* { * {
* alert( 'The editor named ' + e.editor.name + ' is now focused' ); * alert( 'The editor named ' + e.editor.name + ' is now focused' );
* }); * });
*/ */
/** /**
* Fired when the editor instance loses the input focus. * Fired when the editor instance loses the input focus.
* @name CKEDITOR.editor#blur * @name CKEDITOR.editor#blur
* @event * @event
* @param {CKEDITOR.editor} editor The editor instance. * @param {CKEDITOR.editor} editor The editor instance.
* @example * @example
* editor.on( 'blur', function( e ) * editor.on( 'blur', function( e )
* { * {
* alert( 'The editor named ' + e.editor.name + ' lost the focus' ); * alert( 'The editor named ' + e.editor.name + ' lost the focus' );
* }); * });
*/ */

View File

@@ -1,224 +1,224 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* Creates a {@link CKEDITOR.htmlParser} class instance. * Creates a {@link CKEDITOR.htmlParser} class instance.
* @class Provides an "event like" system to parse strings of HTML data. * @class Provides an "event like" system to parse strings of HTML data.
* @example * @example
* var parser = new CKEDITOR.htmlParser(); * var parser = new CKEDITOR.htmlParser();
* parser.onTagOpen = function( tagName, attributes, selfClosing ) * parser.onTagOpen = function( tagName, attributes, selfClosing )
* { * {
* alert( tagName ); * alert( tagName );
* }; * };
* parser.parse( '&lt;p&gt;Some &lt;b&gt;text&lt;/b&gt;.&lt;/p&gt;' ); * parser.parse( '&lt;p&gt;Some &lt;b&gt;text&lt;/b&gt;.&lt;/p&gt;' );
*/ */
CKEDITOR.htmlParser = function() CKEDITOR.htmlParser = function()
{ {
this._ = this._ =
{ {
htmlPartsRegex : new RegExp( '<(?:(?:\\/([^>]+)>)|(?:!--([\\S|\\s]*?)-->)|(?:([^\\s>]+)\\s*((?:(?:"[^"]*")|(?:\'[^\']*\')|[^"\'>])*)\\/?>))', 'g' ) htmlPartsRegex : new RegExp( '<(?:(?:\\/([^>]+)>)|(?:!--([\\S|\\s]*?)-->)|(?:([^\\s>]+)\\s*((?:(?:"[^"]*")|(?:\'[^\']*\')|[^"\'>])*)\\/?>))', 'g' )
}; };
}; };
(function() (function()
{ {
var attribsRegex = /([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g, var attribsRegex = /([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,
emptyAttribs = {checked:1,compact:1,declare:1,defer:1,disabled:1,ismap:1,multiple:1,nohref:1,noresize:1,noshade:1,nowrap:1,readonly:1,selected:1}; emptyAttribs = {checked:1,compact:1,declare:1,defer:1,disabled:1,ismap:1,multiple:1,nohref:1,noresize:1,noshade:1,nowrap:1,readonly:1,selected:1};
CKEDITOR.htmlParser.prototype = CKEDITOR.htmlParser.prototype =
{ {
/** /**
* Function to be fired when a tag opener is found. This function * Function to be fired when a tag opener is found. This function
* should be overriden when using this class. * should be overriden when using this class.
* @param {String} tagName The tag name. The name is guarantted to be * @param {String} tagName The tag name. The name is guarantted to be
* lowercased. * lowercased.
* @param {Object} attributes An object containing all tag attributes. Each * @param {Object} attributes An object containing all tag attributes. Each
* property in this object represent and attribute name and its * property in this object represent and attribute name and its
* value is the attribute value. * value is the attribute value.
* @param {Boolean} selfClosing true if the tag closes itself, false if the * @param {Boolean} selfClosing true if the tag closes itself, false if the
* tag doesn't. * tag doesn't.
* @example * @example
* var parser = new CKEDITOR.htmlParser(); * var parser = new CKEDITOR.htmlParser();
* parser.onTagOpen = function( tagName, attributes, selfClosing ) * parser.onTagOpen = function( tagName, attributes, selfClosing )
* { * {
* alert( tagName ); // e.g. "b" * alert( tagName ); // e.g. "b"
* }); * });
* parser.parse( "&lt;!-- Example --&gt;&lt;b&gt;Hello&lt;/b&gt;" ); * parser.parse( "&lt;!-- Example --&gt;&lt;b&gt;Hello&lt;/b&gt;" );
*/ */
onTagOpen : function() {}, onTagOpen : function() {},
/** /**
* Function to be fired when a tag closer is found. This function * Function to be fired when a tag closer is found. This function
* should be overriden when using this class. * should be overriden when using this class.
* @param {String} tagName The tag name. The name is guarantted to be * @param {String} tagName The tag name. The name is guarantted to be
* lowercased. * lowercased.
* @example * @example
* var parser = new CKEDITOR.htmlParser(); * var parser = new CKEDITOR.htmlParser();
* parser.onTagClose = function( tagName ) * parser.onTagClose = function( tagName )
* { * {
* alert( tagName ); // e.g. "b" * alert( tagName ); // e.g. "b"
* }); * });
* parser.parse( "&lt;!-- Example --&gt;&lt;b&gt;Hello&lt;/b&gt;" ); * parser.parse( "&lt;!-- Example --&gt;&lt;b&gt;Hello&lt;/b&gt;" );
*/ */
onTagClose : function() {}, onTagClose : function() {},
/** /**
* Function to be fired when text is found. This function * Function to be fired when text is found. This function
* should be overriden when using this class. * should be overriden when using this class.
* @param {String} text The text found. * @param {String} text The text found.
* @example * @example
* var parser = new CKEDITOR.htmlParser(); * var parser = new CKEDITOR.htmlParser();
* parser.onText = function( text ) * parser.onText = function( text )
* { * {
* alert( text ); // e.g. "Hello" * alert( text ); // e.g. "Hello"
* }); * });
* parser.parse( "&lt;!-- Example --&gt;&lt;b&gt;Hello&lt;/b&gt;" ); * parser.parse( "&lt;!-- Example --&gt;&lt;b&gt;Hello&lt;/b&gt;" );
*/ */
onText : function() {}, onText : function() {},
/** /**
* Function to be fired when CDATA section is found. This function * Function to be fired when CDATA section is found. This function
* should be overriden when using this class. * should be overriden when using this class.
* @param {String} cdata The CDATA been found. * @param {String} cdata The CDATA been found.
* @example * @example
* var parser = new CKEDITOR.htmlParser(); * var parser = new CKEDITOR.htmlParser();
* parser.onCDATA = function( cdata ) * parser.onCDATA = function( cdata )
* { * {
* alert( cdata ); // e.g. "var hello;" * alert( cdata ); // e.g. "var hello;"
* }); * });
* parser.parse( "&lt;script&gt;var hello;&lt;/script&gt;" ); * parser.parse( "&lt;script&gt;var hello;&lt;/script&gt;" );
*/ */
onCDATA : function() {}, onCDATA : function() {},
/** /**
* Function to be fired when a commend is found. This function * Function to be fired when a commend is found. This function
* should be overriden when using this class. * should be overriden when using this class.
* @param {String} comment The comment text. * @param {String} comment The comment text.
* @example * @example
* var parser = new CKEDITOR.htmlParser(); * var parser = new CKEDITOR.htmlParser();
* parser.onComment = function( comment ) * parser.onComment = function( comment )
* { * {
* alert( comment ); // e.g. " Example " * alert( comment ); // e.g. " Example "
* }); * });
* parser.parse( "&lt;!-- Example --&gt;&lt;b&gt;Hello&lt;/b&gt;" ); * parser.parse( "&lt;!-- Example --&gt;&lt;b&gt;Hello&lt;/b&gt;" );
*/ */
onComment : function() {}, onComment : function() {},
/** /**
* Parses text, looking for HTML tokens, like tag openers or closers, * Parses text, looking for HTML tokens, like tag openers or closers,
* or comments. This function fires the onTagOpen, onTagClose, onText * or comments. This function fires the onTagOpen, onTagClose, onText
* and onComment function during its execution. * and onComment function during its execution.
* @param {String} html The HTML to be parsed. * @param {String} html The HTML to be parsed.
* @example * @example
* var parser = new CKEDITOR.htmlParser(); * var parser = new CKEDITOR.htmlParser();
* // The onTagOpen, onTagClose, onText and onComment should be overriden * // The onTagOpen, onTagClose, onText and onComment should be overriden
* // at this point. * // at this point.
* parser.parse( "&lt;!-- Example --&gt;&lt;b&gt;Hello&lt;/b&gt;" ); * parser.parse( "&lt;!-- Example --&gt;&lt;b&gt;Hello&lt;/b&gt;" );
*/ */
parse : function( html ) parse : function( html )
{ {
var parts, var parts,
tagName, tagName,
nextIndex = 0, nextIndex = 0,
cdata; // The collected data inside a CDATA section. cdata; // The collected data inside a CDATA section.
while ( ( parts = this._.htmlPartsRegex.exec( html ) ) ) while ( ( parts = this._.htmlPartsRegex.exec( html ) ) )
{ {
var tagIndex = parts.index; var tagIndex = parts.index;
if ( tagIndex > nextIndex ) if ( tagIndex > nextIndex )
{ {
var text = html.substring( nextIndex, tagIndex ); var text = html.substring( nextIndex, tagIndex );
if ( cdata ) if ( cdata )
cdata.push( text ); cdata.push( text );
else else
this.onText( text ); this.onText( text );
} }
nextIndex = this._.htmlPartsRegex.lastIndex; nextIndex = this._.htmlPartsRegex.lastIndex;
/* /*
"parts" is an array with the following items: "parts" is an array with the following items:
0 : The entire match for opening/closing tags and comments. 0 : The entire match for opening/closing tags and comments.
1 : Group filled with the tag name for closing tags. 1 : Group filled with the tag name for closing tags.
2 : Group filled with the comment text. 2 : Group filled with the comment text.
3 : Group filled with the tag name for opening tags. 3 : Group filled with the tag name for opening tags.
4 : Group filled with the attributes part of opening tags. 4 : Group filled with the attributes part of opening tags.
*/ */
// Closing tag // Closing tag
if ( ( tagName = parts[ 1 ] ) ) if ( ( tagName = parts[ 1 ] ) )
{ {
tagName = tagName.toLowerCase(); tagName = tagName.toLowerCase();
if ( cdata && CKEDITOR.dtd.$cdata[ tagName ] ) if ( cdata && CKEDITOR.dtd.$cdata[ tagName ] )
{ {
// Send the CDATA data. // Send the CDATA data.
this.onCDATA( cdata.join('') ); this.onCDATA( cdata.join('') );
cdata = null; cdata = null;
} }
if ( !cdata ) if ( !cdata )
{ {
this.onTagClose( tagName ); this.onTagClose( tagName );
continue; continue;
} }
} }
// If CDATA is enabled, just save the raw match. // If CDATA is enabled, just save the raw match.
if ( cdata ) if ( cdata )
{ {
cdata.push( parts[ 0 ] ); cdata.push( parts[ 0 ] );
continue; continue;
} }
// Opening tag // Opening tag
if ( ( tagName = parts[ 3 ] ) ) if ( ( tagName = parts[ 3 ] ) )
{ {
tagName = tagName.toLowerCase(); tagName = tagName.toLowerCase();
// There are some tag names that can break things, so let's // There are some tag names that can break things, so let's
// simply ignore them when parsing. (#5224) // simply ignore them when parsing. (#5224)
if ( /="/.test( tagName ) ) if ( /="/.test( tagName ) )
continue; continue;
var attribs = {}, var attribs = {},
attribMatch, attribMatch,
attribsPart = parts[ 4 ], attribsPart = parts[ 4 ],
selfClosing = !!( attribsPart && attribsPart.charAt( attribsPart.length - 1 ) == '/' ); selfClosing = !!( attribsPart && attribsPart.charAt( attribsPart.length - 1 ) == '/' );
if ( attribsPart ) if ( attribsPart )
{ {
while ( ( attribMatch = attribsRegex.exec( attribsPart ) ) ) while ( ( attribMatch = attribsRegex.exec( attribsPart ) ) )
{ {
var attName = attribMatch[1].toLowerCase(), var attName = attribMatch[1].toLowerCase(),
attValue = attribMatch[2] || attribMatch[3] || attribMatch[4] || ''; attValue = attribMatch[2] || attribMatch[3] || attribMatch[4] || '';
if ( !attValue && emptyAttribs[ attName ] ) if ( !attValue && emptyAttribs[ attName ] )
attribs[ attName ] = attName; attribs[ attName ] = attName;
else else
attribs[ attName ] = attValue; attribs[ attName ] = attValue;
} }
} }
this.onTagOpen( tagName, attribs, selfClosing ); this.onTagOpen( tagName, attribs, selfClosing );
// Open CDATA mode when finding the appropriate tags. // Open CDATA mode when finding the appropriate tags.
if ( !cdata && CKEDITOR.dtd.$cdata[ tagName ] ) if ( !cdata && CKEDITOR.dtd.$cdata[ tagName ] )
cdata = []; cdata = [];
continue; continue;
} }
// Comment // Comment
if ( ( tagName = parts[ 2 ] ) ) if ( ( tagName = parts[ 2 ] ) )
this.onComment( tagName ); this.onComment( tagName );
} }
if ( html.length > nextIndex ) if ( html.length > nextIndex )
this.onText( html.substring( nextIndex, html.length ) ); this.onText( html.substring( nextIndex, html.length ) );
} }
}; };
})(); })();

View File

@@ -1,145 +1,145 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
CKEDITOR.htmlParser.basicWriter = CKEDITOR.tools.createClass( CKEDITOR.htmlParser.basicWriter = CKEDITOR.tools.createClass(
{ {
$ : function() $ : function()
{ {
this._ = this._ =
{ {
output : [] output : []
}; };
}, },
proto : proto :
{ {
/** /**
* Writes the tag opening part for a opener tag. * Writes the tag opening part for a opener tag.
* @param {String} tagName The element name for this tag. * @param {String} tagName The element name for this tag.
* @param {Object} attributes The attributes defined for this tag. The * @param {Object} attributes The attributes defined for this tag. The
* attributes could be used to inspect the tag. * attributes could be used to inspect the tag.
* @example * @example
* // Writes "&lt;p". * // Writes "&lt;p".
* writer.openTag( 'p', { class : 'MyClass', id : 'MyId' } ); * writer.openTag( 'p', { class : 'MyClass', id : 'MyId' } );
*/ */
openTag : function( tagName, attributes ) openTag : function( tagName, attributes )
{ {
this._.output.push( '<', tagName ); this._.output.push( '<', tagName );
}, },
/** /**
* Writes the tag closing part for a opener tag. * Writes the tag closing part for a opener tag.
* @param {String} tagName The element name for this tag. * @param {String} tagName The element name for this tag.
* @param {Boolean} isSelfClose Indicates that this is a self-closing tag, * @param {Boolean} isSelfClose Indicates that this is a self-closing tag,
* like "br" or "img". * like "br" or "img".
* @example * @example
* // Writes "&gt;". * // Writes "&gt;".
* writer.openTagClose( 'p', false ); * writer.openTagClose( 'p', false );
* @example * @example
* // Writes " /&gt;". * // Writes " /&gt;".
* writer.openTagClose( 'br', true ); * writer.openTagClose( 'br', true );
*/ */
openTagClose : function( tagName, isSelfClose ) openTagClose : function( tagName, isSelfClose )
{ {
if ( isSelfClose ) if ( isSelfClose )
this._.output.push( ' />' ); this._.output.push( ' />' );
else else
this._.output.push( '>' ); this._.output.push( '>' );
}, },
/** /**
* Writes an attribute. This function should be called after opening the * Writes an attribute. This function should be called after opening the
* tag with {@link #openTagClose}. * tag with {@link #openTagClose}.
* @param {String} attName The attribute name. * @param {String} attName The attribute name.
* @param {String} attValue The attribute value. * @param {String} attValue The attribute value.
* @example * @example
* // Writes ' class="MyClass"'. * // Writes ' class="MyClass"'.
* writer.attribute( 'class', 'MyClass' ); * writer.attribute( 'class', 'MyClass' );
*/ */
attribute : function( attName, attValue ) attribute : function( attName, attValue )
{ {
// Browsers don't always escape special character in attribute values. (#4683, #4719). // Browsers don't always escape special character in attribute values. (#4683, #4719).
if ( typeof attValue == 'string' ) if ( typeof attValue == 'string' )
attValue = CKEDITOR.tools.htmlEncodeAttr( attValue ); attValue = CKEDITOR.tools.htmlEncodeAttr( attValue );
this._.output.push( ' ', attName, '="', attValue, '"' ); this._.output.push( ' ', attName, '="', attValue, '"' );
}, },
/** /**
* Writes a closer tag. * Writes a closer tag.
* @param {String} tagName The element name for this tag. * @param {String} tagName The element name for this tag.
* @example * @example
* // Writes "&lt;/p&gt;". * // Writes "&lt;/p&gt;".
* writer.closeTag( 'p' ); * writer.closeTag( 'p' );
*/ */
closeTag : function( tagName ) closeTag : function( tagName )
{ {
this._.output.push( '</', tagName, '>' ); this._.output.push( '</', tagName, '>' );
}, },
/** /**
* Writes text. * Writes text.
* @param {String} text The text value * @param {String} text The text value
* @example * @example
* // Writes "Hello Word". * // Writes "Hello Word".
* writer.text( 'Hello Word' ); * writer.text( 'Hello Word' );
*/ */
text : function( text ) text : function( text )
{ {
this._.output.push( text ); this._.output.push( text );
}, },
/** /**
* Writes a comment. * Writes a comment.
* @param {String} comment The comment text. * @param {String} comment The comment text.
* @example * @example
* // Writes "&lt;!-- My comment --&gt;". * // Writes "&lt;!-- My comment --&gt;".
* writer.comment( ' My comment ' ); * writer.comment( ' My comment ' );
*/ */
comment : function( comment ) comment : function( comment )
{ {
this._.output.push( '<!--', comment, '-->' ); this._.output.push( '<!--', comment, '-->' );
}, },
/** /**
* Writes any kind of data to the ouput. * Writes any kind of data to the ouput.
* @example * @example
* writer.write( 'This is an &lt;b&gt;example&lt;/b&gt;.' ); * writer.write( 'This is an &lt;b&gt;example&lt;/b&gt;.' );
*/ */
write : function( data ) write : function( data )
{ {
this._.output.push( data ); this._.output.push( data );
}, },
/** /**
* Empties the current output buffer. * Empties the current output buffer.
* @example * @example
* writer.reset(); * writer.reset();
*/ */
reset : function() reset : function()
{ {
this._.output = []; this._.output = [];
this._.indent = false; this._.indent = false;
}, },
/** /**
* Empties the current output buffer. * Empties the current output buffer.
* @param {Boolean} reset Indicates that the {@link reset} function is to * @param {Boolean} reset Indicates that the {@link reset} function is to
* be automatically called after retrieving the HTML. * be automatically called after retrieving the HTML.
* @returns {String} The HTML written to the writer so far. * @returns {String} The HTML written to the writer so far.
* @example * @example
* var html = writer.getHtml(); * var html = writer.getHtml();
*/ */
getHtml : function( reset ) getHtml : function( reset )
{ {
var html = this._.output.join( '' ); var html = this._.output.join( '' );
if ( reset ) if ( reset )
this.reset(); this.reset();
return html; return html;
} }
} }
}); });

View File

@@ -1,43 +1,43 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
(function() (function()
{ {
/** /**
* A lightweight representation of HTML text. * A lightweight representation of HTML text.
* @constructor * @constructor
* @example * @example
*/ */
CKEDITOR.htmlParser.cdata = function( value ) CKEDITOR.htmlParser.cdata = function( value )
{ {
/** /**
* The CDATA value. * The CDATA value.
* @type String * @type String
* @example * @example
*/ */
this.value = value; this.value = value;
}; };
CKEDITOR.htmlParser.cdata.prototype = CKEDITOR.htmlParser.cdata.prototype =
{ {
/** /**
* CDATA has the same type as {@link CKEDITOR.htmlParser.text} This is * CDATA has the same type as {@link CKEDITOR.htmlParser.text} This is
* a constant value set to {@link CKEDITOR.NODE_TEXT}. * a constant value set to {@link CKEDITOR.NODE_TEXT}.
* @type Number * @type Number
* @example * @example
*/ */
type : CKEDITOR.NODE_TEXT, type : CKEDITOR.NODE_TEXT,
/** /**
* Writes write the CDATA with no special manipulations. * Writes write the CDATA with no special manipulations.
* @param {CKEDITOR.htmlWriter} writer The writer to which write the HTML. * @param {CKEDITOR.htmlWriter} writer The writer to which write the HTML.
*/ */
writeHtml : function( writer ) writeHtml : function( writer )
{ {
writer.write( this.value ); writer.write( this.value );
} }
}; };
})(); })();

View File

@@ -1,60 +1,60 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* A lightweight representation of an HTML comment. * A lightweight representation of an HTML comment.
* @constructor * @constructor
* @example * @example
*/ */
CKEDITOR.htmlParser.comment = function( value ) CKEDITOR.htmlParser.comment = function( value )
{ {
/** /**
* The comment text. * The comment text.
* @type String * @type String
* @example * @example
*/ */
this.value = value; this.value = value;
/** @private */ /** @private */
this._ = this._ =
{ {
isBlockLike : false isBlockLike : false
}; };
}; };
CKEDITOR.htmlParser.comment.prototype = CKEDITOR.htmlParser.comment.prototype =
{ {
/** /**
* The node type. This is a constant value set to {@link CKEDITOR.NODE_COMMENT}. * The node type. This is a constant value set to {@link CKEDITOR.NODE_COMMENT}.
* @type Number * @type Number
* @example * @example
*/ */
type : CKEDITOR.NODE_COMMENT, type : CKEDITOR.NODE_COMMENT,
/** /**
* Writes the HTML representation of this comment to a CKEDITOR.htmlWriter. * Writes the HTML representation of this comment to a CKEDITOR.htmlWriter.
* @param {CKEDITOR.htmlWriter} writer The writer to which write the HTML. * @param {CKEDITOR.htmlWriter} writer The writer to which write the HTML.
* @example * @example
*/ */
writeHtml : function( writer, filter ) writeHtml : function( writer, filter )
{ {
var comment = this.value; var comment = this.value;
if ( filter ) if ( filter )
{ {
if ( !( comment = filter.onComment( comment, this ) ) ) if ( !( comment = filter.onComment( comment, this ) ) )
return; return;
if ( typeof comment != 'string' ) if ( typeof comment != 'string' )
{ {
comment.parent = this.parent; comment.parent = this.parent;
comment.writeHtml( writer, filter ); comment.writeHtml( writer, filter );
return; return;
} }
} }
writer.comment( comment ); writer.comment( comment );
} }
}; };

View File

@@ -1,306 +1,306 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* A lightweight representation of an HTML element. * A lightweight representation of an HTML element.
* @param {String} name The element name. * @param {String} name The element name.
* @param {Object} attributes And object holding all attributes defined for * @param {Object} attributes And object holding all attributes defined for
* this element. * this element.
* @constructor * @constructor
* @example * @example
*/ */
CKEDITOR.htmlParser.element = function( name, attributes ) CKEDITOR.htmlParser.element = function( name, attributes )
{ {
/** /**
* The element name. * The element name.
* @type String * @type String
* @example * @example
*/ */
this.name = name; this.name = name;
/** /**
* Holds the attributes defined for this element. * Holds the attributes defined for this element.
* @type Object * @type Object
* @example * @example
*/ */
this.attributes = attributes || {}; this.attributes = attributes || {};
/** /**
* The nodes that are direct children of this element. * The nodes that are direct children of this element.
* @type Array * @type Array
* @example * @example
*/ */
this.children = []; this.children = [];
// Reveal the real semantic of our internal custom tag name (#6639), // Reveal the real semantic of our internal custom tag name (#6639),
// when resolving whether it's block like. // when resolving whether it's block like.
var realName = name || '', var realName = name || '',
prefixed = realName.match( /^cke:(.*)/ ); prefixed = realName.match( /^cke:(.*)/ );
prefixed && ( realName = prefixed[ 1 ] ); prefixed && ( realName = prefixed[ 1 ] );
var isBlockLike = !!( CKEDITOR.dtd.$nonBodyContent[ realName ] var isBlockLike = !!( CKEDITOR.dtd.$nonBodyContent[ realName ]
|| CKEDITOR.dtd.$block[ realName ] || CKEDITOR.dtd.$block[ realName ]
|| CKEDITOR.dtd.$listItem[ realName ] || CKEDITOR.dtd.$listItem[ realName ]
|| CKEDITOR.dtd.$tableContent[ realName ] || CKEDITOR.dtd.$tableContent[ realName ]
|| CKEDITOR.dtd.$nonEditable[ realName ] || CKEDITOR.dtd.$nonEditable[ realName ]
|| realName == 'br' ); || realName == 'br' );
this.isEmpty = !!CKEDITOR.dtd.$empty[ name ]; this.isEmpty = !!CKEDITOR.dtd.$empty[ name ];
this.isUnknown = !CKEDITOR.dtd[ name ]; this.isUnknown = !CKEDITOR.dtd[ name ];
/** @private */ /** @private */
this._ = this._ =
{ {
isBlockLike : isBlockLike, isBlockLike : isBlockLike,
hasInlineStarted : this.isEmpty || !isBlockLike hasInlineStarted : this.isEmpty || !isBlockLike
}; };
}; };
/** /**
* Object presentation of CSS style declaration text. * Object presentation of CSS style declaration text.
* @param {CKEDITOR.htmlParser.element|String} elementOrStyleText A html parser element or the inline style text. * @param {CKEDITOR.htmlParser.element|String} elementOrStyleText A html parser element or the inline style text.
*/ */
CKEDITOR.htmlParser.cssStyle = function() CKEDITOR.htmlParser.cssStyle = function()
{ {
var styleText, var styleText,
arg = arguments[ 0 ], arg = arguments[ 0 ],
rules = {}; rules = {};
styleText = arg instanceof CKEDITOR.htmlParser.element ? arg.attributes.style : arg; styleText = arg instanceof CKEDITOR.htmlParser.element ? arg.attributes.style : arg;
// html-encoded quote might be introduced by 'font-family' // html-encoded quote might be introduced by 'font-family'
// from MS-Word which confused the following regexp. e.g. // from MS-Word which confused the following regexp. e.g.
//'font-family: &quot;Lucida, Console&quot;' //'font-family: &quot;Lucida, Console&quot;'
( styleText || '' ) ( styleText || '' )
.replace( /&quot;/g, '"' ) .replace( /&quot;/g, '"' )
.replace( /\s*([^ :;]+)\s*:\s*([^;]+)\s*(?=;|$)/g, .replace( /\s*([^ :;]+)\s*:\s*([^;]+)\s*(?=;|$)/g,
function( match, name, value ) function( match, name, value )
{ {
name == 'font-family' && ( value = value.replace( /["']/g, '' ) ); name == 'font-family' && ( value = value.replace( /["']/g, '' ) );
rules[ name.toLowerCase() ] = value; rules[ name.toLowerCase() ] = value;
}); });
return { return {
rules : rules, rules : rules,
/** /**
* Apply the styles onto the specified element or object. * Apply the styles onto the specified element or object.
* @param {CKEDITOR.htmlParser.element|CKEDITOR.dom.element|Object} obj * @param {CKEDITOR.htmlParser.element|CKEDITOR.dom.element|Object} obj
*/ */
populate : function( obj ) populate : function( obj )
{ {
var style = this.toString(); var style = this.toString();
if ( style ) if ( style )
{ {
obj instanceof CKEDITOR.dom.element ? obj instanceof CKEDITOR.dom.element ?
obj.setAttribute( 'style', style ) : obj.setAttribute( 'style', style ) :
obj instanceof CKEDITOR.htmlParser.element ? obj instanceof CKEDITOR.htmlParser.element ?
obj.attributes.style = style : obj.attributes.style = style :
obj.style = style; obj.style = style;
} }
}, },
toString : function() toString : function()
{ {
var output = []; var output = [];
for ( var i in rules ) for ( var i in rules )
rules[ i ] && output.push( i, ':', rules[ i ], ';' ); rules[ i ] && output.push( i, ':', rules[ i ], ';' );
return output.join( '' ); return output.join( '' );
} }
}; };
}; };
(function() (function()
{ {
// Used to sort attribute entries in an array, where the first element of // Used to sort attribute entries in an array, where the first element of
// each object is the attribute name. // each object is the attribute name.
var sortAttribs = function( a, b ) var sortAttribs = function( a, b )
{ {
a = a[0]; a = a[0];
b = b[0]; b = b[0];
return a < b ? -1 : a > b ? 1 : 0; return a < b ? -1 : a > b ? 1 : 0;
}; };
CKEDITOR.htmlParser.element.prototype = CKEDITOR.htmlParser.element.prototype =
{ {
/** /**
* The node type. This is a constant value set to {@link CKEDITOR.NODE_ELEMENT}. * The node type. This is a constant value set to {@link CKEDITOR.NODE_ELEMENT}.
* @type Number * @type Number
* @example * @example
*/ */
type : CKEDITOR.NODE_ELEMENT, type : CKEDITOR.NODE_ELEMENT,
/** /**
* Adds a node to the element children list. * Adds a node to the element children list.
* @param {Object} node The node to be added. It can be any of of the * @param {Object} node The node to be added. It can be any of of the
* following types: {@link CKEDITOR.htmlParser.element}, * following types: {@link CKEDITOR.htmlParser.element},
* {@link CKEDITOR.htmlParser.text} and * {@link CKEDITOR.htmlParser.text} and
* {@link CKEDITOR.htmlParser.comment}. * {@link CKEDITOR.htmlParser.comment}.
* @function * @function
* @example * @example
*/ */
add : CKEDITOR.htmlParser.fragment.prototype.add, add : CKEDITOR.htmlParser.fragment.prototype.add,
/** /**
* Clone this element. * Clone this element.
* @returns {CKEDITOR.htmlParser.element} The element clone. * @returns {CKEDITOR.htmlParser.element} The element clone.
* @example * @example
*/ */
clone : function() clone : function()
{ {
return new CKEDITOR.htmlParser.element( this.name, this.attributes ); return new CKEDITOR.htmlParser.element( this.name, this.attributes );
}, },
/** /**
* Writes the element HTML to a CKEDITOR.htmlWriter. * Writes the element HTML to a CKEDITOR.htmlWriter.
* @param {CKEDITOR.htmlWriter} writer The writer to which write the HTML. * @param {CKEDITOR.htmlWriter} writer The writer to which write the HTML.
* @example * @example
*/ */
writeHtml : function( writer, filter ) writeHtml : function( writer, filter )
{ {
var attributes = this.attributes; var attributes = this.attributes;
// Ignore cke: prefixes when writing HTML. // Ignore cke: prefixes when writing HTML.
var element = this, var element = this,
writeName = element.name, writeName = element.name,
a, newAttrName, value; a, newAttrName, value;
var isChildrenFiltered; var isChildrenFiltered;
/** /**
* Providing an option for bottom-up filtering order ( element * Providing an option for bottom-up filtering order ( element
* children to be pre-filtered before the element itself ). * children to be pre-filtered before the element itself ).
*/ */
element.filterChildren = function() element.filterChildren = function()
{ {
if ( !isChildrenFiltered ) if ( !isChildrenFiltered )
{ {
var writer = new CKEDITOR.htmlParser.basicWriter(); var writer = new CKEDITOR.htmlParser.basicWriter();
CKEDITOR.htmlParser.fragment.prototype.writeChildrenHtml.call( element, writer, filter ); CKEDITOR.htmlParser.fragment.prototype.writeChildrenHtml.call( element, writer, filter );
element.children = new CKEDITOR.htmlParser.fragment.fromHtml( writer.getHtml(), 0, element.clone() ).children; element.children = new CKEDITOR.htmlParser.fragment.fromHtml( writer.getHtml(), 0, element.clone() ).children;
isChildrenFiltered = 1; isChildrenFiltered = 1;
} }
}; };
if ( filter ) if ( filter )
{ {
while ( true ) while ( true )
{ {
if ( !( writeName = filter.onElementName( writeName ) ) ) if ( !( writeName = filter.onElementName( writeName ) ) )
return; return;
element.name = writeName; element.name = writeName;
if ( !( element = filter.onElement( element ) ) ) if ( !( element = filter.onElement( element ) ) )
return; return;
element.parent = this.parent; element.parent = this.parent;
if ( element.name == writeName ) if ( element.name == writeName )
break; break;
// If the element has been replaced with something of a // If the element has been replaced with something of a
// different type, then make the replacement write itself. // different type, then make the replacement write itself.
if ( element.type != CKEDITOR.NODE_ELEMENT ) if ( element.type != CKEDITOR.NODE_ELEMENT )
{ {
element.writeHtml( writer, filter ); element.writeHtml( writer, filter );
return; return;
} }
writeName = element.name; writeName = element.name;
// This indicate that the element has been dropped by // This indicate that the element has been dropped by
// filter but not the children. // filter but not the children.
if ( !writeName ) if ( !writeName )
{ {
// Fix broken parent refs. // Fix broken parent refs.
for ( var c = 0, length = this.children.length ; c < length ; c++ ) for ( var c = 0, length = this.children.length ; c < length ; c++ )
this.children[ c ].parent = element.parent; this.children[ c ].parent = element.parent;
this.writeChildrenHtml.call( element, writer, isChildrenFiltered ? null : filter ); this.writeChildrenHtml.call( element, writer, isChildrenFiltered ? null : filter );
return; return;
} }
} }
// The element may have been changed, so update the local // The element may have been changed, so update the local
// references. // references.
attributes = element.attributes; attributes = element.attributes;
} }
// Open element tag. // Open element tag.
writer.openTag( writeName, attributes ); writer.openTag( writeName, attributes );
// Copy all attributes to an array. // Copy all attributes to an array.
var attribsArray = []; var attribsArray = [];
// Iterate over the attributes twice since filters may alter // Iterate over the attributes twice since filters may alter
// other attributes. // other attributes.
for ( var i = 0 ; i < 2; i++ ) for ( var i = 0 ; i < 2; i++ )
{ {
for ( a in attributes ) for ( a in attributes )
{ {
newAttrName = a; newAttrName = a;
value = attributes[ a ]; value = attributes[ a ];
if ( i == 1 ) if ( i == 1 )
attribsArray.push( [ a, value ] ); attribsArray.push( [ a, value ] );
else if ( filter ) else if ( filter )
{ {
while ( true ) while ( true )
{ {
if ( !( newAttrName = filter.onAttributeName( a ) ) ) if ( !( newAttrName = filter.onAttributeName( a ) ) )
{ {
delete attributes[ a ]; delete attributes[ a ];
break; break;
} }
else if ( newAttrName != a ) else if ( newAttrName != a )
{ {
delete attributes[ a ]; delete attributes[ a ];
a = newAttrName; a = newAttrName;
continue; continue;
} }
else else
break; break;
} }
if ( newAttrName ) if ( newAttrName )
{ {
if ( ( value = filter.onAttribute( element, newAttrName, value ) ) === false ) if ( ( value = filter.onAttribute( element, newAttrName, value ) ) === false )
delete attributes[ newAttrName ]; delete attributes[ newAttrName ];
else else
attributes [ newAttrName ] = value; attributes [ newAttrName ] = value;
} }
} }
} }
} }
// Sort the attributes by name. // Sort the attributes by name.
if ( writer.sortAttributes ) if ( writer.sortAttributes )
attribsArray.sort( sortAttribs ); attribsArray.sort( sortAttribs );
// Send the attributes. // Send the attributes.
var len = attribsArray.length; var len = attribsArray.length;
for ( i = 0 ; i < len ; i++ ) for ( i = 0 ; i < len ; i++ )
{ {
var attrib = attribsArray[ i ]; var attrib = attribsArray[ i ];
writer.attribute( attrib[0], attrib[1] ); writer.attribute( attrib[0], attrib[1] );
} }
// Close the tag. // Close the tag.
writer.openTagClose( writeName, element.isEmpty ); writer.openTagClose( writeName, element.isEmpty );
if ( !element.isEmpty ) if ( !element.isEmpty )
{ {
this.writeChildrenHtml.call( element, writer, isChildrenFiltered ? null : filter ); this.writeChildrenHtml.call( element, writer, isChildrenFiltered ? null : filter );
// Close the element. // Close the element.
writer.closeTag( writeName ); writer.closeTag( writeName );
} }
}, },
writeChildrenHtml : function( writer, filter ) writeChildrenHtml : function( writer, filter )
{ {
// Send children. // Send children.
CKEDITOR.htmlParser.fragment.prototype.writeChildrenHtml.apply( this, arguments ); CKEDITOR.htmlParser.fragment.prototype.writeChildrenHtml.apply( this, arguments );
} }
}; };
})(); })();

View File

@@ -1,288 +1,288 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
(function() (function()
{ {
CKEDITOR.htmlParser.filter = CKEDITOR.tools.createClass( CKEDITOR.htmlParser.filter = CKEDITOR.tools.createClass(
{ {
$ : function( rules ) $ : function( rules )
{ {
this._ = this._ =
{ {
elementNames : [], elementNames : [],
attributeNames : [], attributeNames : [],
elements : { $length : 0 }, elements : { $length : 0 },
attributes : { $length : 0 } attributes : { $length : 0 }
}; };
if ( rules ) if ( rules )
this.addRules( rules, 10 ); this.addRules( rules, 10 );
}, },
proto : proto :
{ {
addRules : function( rules, priority ) addRules : function( rules, priority )
{ {
if ( typeof priority != 'number' ) if ( typeof priority != 'number' )
priority = 10; priority = 10;
// Add the elementNames. // Add the elementNames.
addItemsToList( this._.elementNames, rules.elementNames, priority ); addItemsToList( this._.elementNames, rules.elementNames, priority );
// Add the attributeNames. // Add the attributeNames.
addItemsToList( this._.attributeNames, rules.attributeNames, priority ); addItemsToList( this._.attributeNames, rules.attributeNames, priority );
// Add the elements. // Add the elements.
addNamedItems( this._.elements, rules.elements, priority ); addNamedItems( this._.elements, rules.elements, priority );
// Add the attributes. // Add the attributes.
addNamedItems( this._.attributes, rules.attributes, priority ); addNamedItems( this._.attributes, rules.attributes, priority );
// Add the text. // Add the text.
this._.text = transformNamedItem( this._.text, rules.text, priority ) || this._.text; this._.text = transformNamedItem( this._.text, rules.text, priority ) || this._.text;
// Add the comment. // Add the comment.
this._.comment = transformNamedItem( this._.comment, rules.comment, priority ) || this._.comment; this._.comment = transformNamedItem( this._.comment, rules.comment, priority ) || this._.comment;
// Add root fragment. // Add root fragment.
this._.root = transformNamedItem( this._.root, rules.root, priority ) || this._.root; this._.root = transformNamedItem( this._.root, rules.root, priority ) || this._.root;
}, },
onElementName : function( name ) onElementName : function( name )
{ {
return filterName( name, this._.elementNames ); return filterName( name, this._.elementNames );
}, },
onAttributeName : function( name ) onAttributeName : function( name )
{ {
return filterName( name, this._.attributeNames ); return filterName( name, this._.attributeNames );
}, },
onText : function( text ) onText : function( text )
{ {
var textFilter = this._.text; var textFilter = this._.text;
return textFilter ? textFilter.filter( text ) : text; return textFilter ? textFilter.filter( text ) : text;
}, },
onComment : function( commentText, comment ) onComment : function( commentText, comment )
{ {
var textFilter = this._.comment; var textFilter = this._.comment;
return textFilter ? textFilter.filter( commentText, comment ) : commentText; return textFilter ? textFilter.filter( commentText, comment ) : commentText;
}, },
onFragment : function( element ) onFragment : function( element )
{ {
var rootFilter = this._.root; var rootFilter = this._.root;
return rootFilter ? rootFilter.filter( element ) : element; return rootFilter ? rootFilter.filter( element ) : element;
}, },
onElement : function( element ) onElement : function( element )
{ {
// We must apply filters set to the specific element name as // We must apply filters set to the specific element name as
// well as those set to the generic $ name. So, add both to an // well as those set to the generic $ name. So, add both to an
// array and process them in a small loop. // array and process them in a small loop.
var filters = [ this._.elements[ '^' ], this._.elements[ element.name ], this._.elements.$ ], var filters = [ this._.elements[ '^' ], this._.elements[ element.name ], this._.elements.$ ],
filter, ret; filter, ret;
for ( var i = 0 ; i < 3 ; i++ ) for ( var i = 0 ; i < 3 ; i++ )
{ {
filter = filters[ i ]; filter = filters[ i ];
if ( filter ) if ( filter )
{ {
ret = filter.filter( element, this ); ret = filter.filter( element, this );
if ( ret === false ) if ( ret === false )
return null; return null;
if ( ret && ret != element ) if ( ret && ret != element )
return this.onNode( ret ); return this.onNode( ret );
// The non-root element has been dismissed by one of the filters. // The non-root element has been dismissed by one of the filters.
if ( element.parent && !element.name ) if ( element.parent && !element.name )
break; break;
} }
} }
return element; return element;
}, },
onNode : function( node ) onNode : function( node )
{ {
var type = node.type; var type = node.type;
return type == CKEDITOR.NODE_ELEMENT ? this.onElement( node ) : return type == CKEDITOR.NODE_ELEMENT ? this.onElement( node ) :
type == CKEDITOR.NODE_TEXT ? new CKEDITOR.htmlParser.text( this.onText( node.value ) ) : type == CKEDITOR.NODE_TEXT ? new CKEDITOR.htmlParser.text( this.onText( node.value ) ) :
type == CKEDITOR.NODE_COMMENT ? new CKEDITOR.htmlParser.comment( this.onComment( node.value ) ): type == CKEDITOR.NODE_COMMENT ? new CKEDITOR.htmlParser.comment( this.onComment( node.value ) ):
null; null;
}, },
onAttribute : function( element, name, value ) onAttribute : function( element, name, value )
{ {
var filter = this._.attributes[ name ]; var filter = this._.attributes[ name ];
if ( filter ) if ( filter )
{ {
var ret = filter.filter( value, element, this ); var ret = filter.filter( value, element, this );
if ( ret === false ) if ( ret === false )
return false; return false;
if ( typeof ret != 'undefined' ) if ( typeof ret != 'undefined' )
return ret; return ret;
} }
return value; return value;
} }
} }
}); });
function filterName( name, filters ) function filterName( name, filters )
{ {
for ( var i = 0 ; name && i < filters.length ; i++ ) for ( var i = 0 ; name && i < filters.length ; i++ )
{ {
var filter = filters[ i ]; var filter = filters[ i ];
name = name.replace( filter[ 0 ], filter[ 1 ] ); name = name.replace( filter[ 0 ], filter[ 1 ] );
} }
return name; return name;
} }
function addItemsToList( list, items, priority ) function addItemsToList( list, items, priority )
{ {
if ( typeof items == 'function' ) if ( typeof items == 'function' )
items = [ items ]; items = [ items ];
var i, j, var i, j,
listLength = list.length, listLength = list.length,
itemsLength = items && items.length; itemsLength = items && items.length;
if ( itemsLength ) if ( itemsLength )
{ {
// Find the index to insert the items at. // Find the index to insert the items at.
for ( i = 0 ; i < listLength && list[ i ].pri < priority ; i++ ) for ( i = 0 ; i < listLength && list[ i ].pri < priority ; i++ )
{ /*jsl:pass*/ } { /*jsl:pass*/ }
// Add all new items to the list at the specific index. // Add all new items to the list at the specific index.
for ( j = itemsLength - 1 ; j >= 0 ; j-- ) for ( j = itemsLength - 1 ; j >= 0 ; j-- )
{ {
var item = items[ j ]; var item = items[ j ];
if ( item ) if ( item )
{ {
item.pri = priority; item.pri = priority;
list.splice( i, 0, item ); list.splice( i, 0, item );
} }
} }
} }
} }
function addNamedItems( hashTable, items, priority ) function addNamedItems( hashTable, items, priority )
{ {
if ( items ) if ( items )
{ {
for ( var name in items ) for ( var name in items )
{ {
var current = hashTable[ name ]; var current = hashTable[ name ];
hashTable[ name ] = hashTable[ name ] =
transformNamedItem( transformNamedItem(
current, current,
items[ name ], items[ name ],
priority ); priority );
if ( !current ) if ( !current )
hashTable.$length++; hashTable.$length++;
} }
} }
} }
function transformNamedItem( current, item, priority ) function transformNamedItem( current, item, priority )
{ {
if ( item ) if ( item )
{ {
item.pri = priority; item.pri = priority;
if ( current ) if ( current )
{ {
// If the current item is not an Array, transform it. // If the current item is not an Array, transform it.
if ( !current.splice ) if ( !current.splice )
{ {
if ( current.pri > priority ) if ( current.pri > priority )
current = [ item, current ]; current = [ item, current ];
else else
current = [ current, item ]; current = [ current, item ];
current.filter = callItems; current.filter = callItems;
} }
else else
addItemsToList( current, item, priority ); addItemsToList( current, item, priority );
return current; return current;
} }
else else
{ {
item.filter = item; item.filter = item;
return item; return item;
} }
} }
} }
// Invoke filters sequentially on the array, break the iteration // Invoke filters sequentially on the array, break the iteration
// when it doesn't make sense to continue anymore. // when it doesn't make sense to continue anymore.
function callItems( currentEntry ) function callItems( currentEntry )
{ {
var isNode = currentEntry.type var isNode = currentEntry.type
|| currentEntry instanceof CKEDITOR.htmlParser.fragment; || currentEntry instanceof CKEDITOR.htmlParser.fragment;
for ( var i = 0 ; i < this.length ; i++ ) for ( var i = 0 ; i < this.length ; i++ )
{ {
// Backup the node info before filtering. // Backup the node info before filtering.
if ( isNode ) if ( isNode )
{ {
var orgType = currentEntry.type, var orgType = currentEntry.type,
orgName = currentEntry.name; orgName = currentEntry.name;
} }
var item = this[ i ], var item = this[ i ],
ret = item.apply( window, arguments ); ret = item.apply( window, arguments );
if ( ret === false ) if ( ret === false )
return ret; return ret;
// We're filtering node (element/fragment). // We're filtering node (element/fragment).
if ( isNode ) if ( isNode )
{ {
// No further filtering if it's not anymore // No further filtering if it's not anymore
// fitable for the subsequent filters. // fitable for the subsequent filters.
if ( ret && ( ret.name != orgName if ( ret && ( ret.name != orgName
|| ret.type != orgType ) ) || ret.type != orgType ) )
{ {
return ret; return ret;
} }
} }
// Filtering value (nodeName/textValue/attrValue). // Filtering value (nodeName/textValue/attrValue).
else else
{ {
// No further filtering if it's not // No further filtering if it's not
// any more values. // any more values.
if ( typeof ret != 'string' ) if ( typeof ret != 'string' )
return ret; return ret;
} }
ret != undefined && ( currentEntry = ret ); ret != undefined && ( currentEntry = ret );
} }
return currentEntry; return currentEntry;
} }
})(); })();
// "entities" plugin // "entities" plugin
/* /*
{ {
text : function( text ) text : function( text )
{ {
// TODO : Process entities. // TODO : Process entities.
return text.toUpperCase(); return text.toUpperCase();
} }
}; };
*/ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,53 +1,53 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
(function() (function()
{ {
/** /**
* A lightweight representation of HTML text. * A lightweight representation of HTML text.
* @constructor * @constructor
* @example * @example
*/ */
CKEDITOR.htmlParser.text = function( value ) CKEDITOR.htmlParser.text = function( value )
{ {
/** /**
* The text value. * The text value.
* @type String * @type String
* @example * @example
*/ */
this.value = value; this.value = value;
/** @private */ /** @private */
this._ = this._ =
{ {
isBlockLike : false isBlockLike : false
}; };
}; };
CKEDITOR.htmlParser.text.prototype = CKEDITOR.htmlParser.text.prototype =
{ {
/** /**
* The node type. This is a constant value set to {@link CKEDITOR.NODE_TEXT}. * The node type. This is a constant value set to {@link CKEDITOR.NODE_TEXT}.
* @type Number * @type Number
* @example * @example
*/ */
type : CKEDITOR.NODE_TEXT, type : CKEDITOR.NODE_TEXT,
/** /**
* Writes the HTML representation of this text to a CKEDITOR.htmlWriter. * Writes the HTML representation of this text to a CKEDITOR.htmlWriter.
* @param {CKEDITOR.htmlWriter} writer The writer to which write the HTML. * @param {CKEDITOR.htmlWriter} writer The writer to which write the HTML.
* @example * @example
*/ */
writeHtml : function( writer, filter ) writeHtml : function( writer, filter )
{ {
var text = this.value; var text = this.value;
if ( filter && !( text = filter.onText( text, this ) ) ) if ( filter && !( text = filter.onText( text, this ) ) )
return; return;
writer.text( text ); writer.text( text );
} }
}; };
})(); })();

View File

@@ -1,157 +1,157 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
(function() (function()
{ {
var loadedLangs = {}; var loadedLangs = {};
/** /**
* @namespace Holds language related functions. * @namespace Holds language related functions.
*/ */
CKEDITOR.lang = CKEDITOR.lang =
{ {
/** /**
* The list of languages available in the editor core. * The list of languages available in the editor core.
* @type Object * @type Object
* @example * @example
* alert( CKEDITOR.lang.en ); // "true" * alert( CKEDITOR.lang.en ); // "true"
*/ */
languages : languages :
{ {
'af' : 1, 'af' : 1,
'ar' : 1, 'ar' : 1,
'bg' : 1, 'bg' : 1,
'bn' : 1, 'bn' : 1,
'bs' : 1, 'bs' : 1,
'ca' : 1, 'ca' : 1,
'cs' : 1, 'cs' : 1,
'cy' : 1, 'cy' : 1,
'da' : 1, 'da' : 1,
'de' : 1, 'de' : 1,
'el' : 1, 'el' : 1,
'en-au' : 1, 'en-au' : 1,
'en-ca' : 1, 'en-ca' : 1,
'en-gb' : 1, 'en-gb' : 1,
'en' : 1, 'en' : 1,
'eo' : 1, 'eo' : 1,
'es' : 1, 'es' : 1,
'et' : 1, 'et' : 1,
'eu' : 1, 'eu' : 1,
'fa' : 1, 'fa' : 1,
'fi' : 1, 'fi' : 1,
'fo' : 1, 'fo' : 1,
'fr-ca' : 1, 'fr-ca' : 1,
'fr' : 1, 'fr' : 1,
'gl' : 1, 'gl' : 1,
'gu' : 1, 'gu' : 1,
'he' : 1, 'he' : 1,
'hi' : 1, 'hi' : 1,
'hr' : 1, 'hr' : 1,
'hu' : 1, 'hu' : 1,
'is' : 1, 'is' : 1,
'it' : 1, 'it' : 1,
'ja' : 1, 'ja' : 1,
'ka' : 1, 'ka' : 1,
'km' : 1, 'km' : 1,
'ko' : 1, 'ko' : 1,
'lt' : 1, 'lt' : 1,
'lv' : 1, 'lv' : 1,
'mn' : 1, 'mn' : 1,
'ms' : 1, 'ms' : 1,
'nb' : 1, 'nb' : 1,
'nl' : 1, 'nl' : 1,
'no' : 1, 'no' : 1,
'pl' : 1, 'pl' : 1,
'pt-br' : 1, 'pt-br' : 1,
'pt' : 1, 'pt' : 1,
'ro' : 1, 'ro' : 1,
'ru' : 1, 'ru' : 1,
'sk' : 1, 'sk' : 1,
'sl' : 1, 'sl' : 1,
'sr-latn' : 1, 'sr-latn' : 1,
'sr' : 1, 'sr' : 1,
'sv' : 1, 'sv' : 1,
'th' : 1, 'th' : 1,
'tr' : 1, 'tr' : 1,
'uk' : 1, 'uk' : 1,
'vi' : 1, 'vi' : 1,
'zh-cn' : 1, 'zh-cn' : 1,
'zh' : 1 'zh' : 1
}, },
/** /**
* Loads a specific language file, or auto detect it. A callback is * Loads a specific language file, or auto detect it. A callback is
* then called when the file gets loaded. * then called when the file gets loaded.
* @param {String} languageCode The code of the language file to be * @param {String} languageCode The code of the language file to be
* loaded. If null or empty, autodetection will be performed. The * loaded. If null or empty, autodetection will be performed. The
* same happens if the language is not supported. * same happens if the language is not supported.
* @param {String} defaultLanguage The language to be used if * @param {String} defaultLanguage The language to be used if
* languageCode is not supported or if the autodetection fails. * languageCode is not supported or if the autodetection fails.
* @param {Function} callback A function to be called once the * @param {Function} callback A function to be called once the
* language file is loaded. Two parameters are passed to this * language file is loaded. Two parameters are passed to this
* function: the language code and the loaded language entries. * function: the language code and the loaded language entries.
* @example * @example
*/ */
load : function( languageCode, defaultLanguage, callback ) load : function( languageCode, defaultLanguage, callback )
{ {
// If no languageCode - fallback to browser or default. // If no languageCode - fallback to browser or default.
// If languageCode - fallback to no-localized version or default. // If languageCode - fallback to no-localized version or default.
if ( !languageCode || !CKEDITOR.lang.languages[ languageCode ] ) if ( !languageCode || !CKEDITOR.lang.languages[ languageCode ] )
languageCode = this.detect( defaultLanguage, languageCode ); languageCode = this.detect( defaultLanguage, languageCode );
if ( !this[ languageCode ] ) if ( !this[ languageCode ] )
{ {
CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( CKEDITOR.scriptLoader.load( CKEDITOR.getUrl(
'_source/' + // @Packager.RemoveLine '_source/' + // @Packager.RemoveLine
'lang/' + languageCode + '.js' ), 'lang/' + languageCode + '.js' ),
function() function()
{ {
callback( languageCode, this[ languageCode ] ); callback( languageCode, this[ languageCode ] );
} }
, this ); , this );
} }
else else
callback( languageCode, this[ languageCode ] ); callback( languageCode, this[ languageCode ] );
}, },
/** /**
* Returns the language that best fit the user language. For example, * Returns the language that best fit the user language. For example,
* suppose that the user language is "pt-br". If this language is * suppose that the user language is "pt-br". If this language is
* supported by the editor, it is returned. Otherwise, if only "pt" is * supported by the editor, it is returned. Otherwise, if only "pt" is
* supported, it is returned instead. If none of the previous are * supported, it is returned instead. If none of the previous are
* supported, a default language is then returned. * supported, a default language is then returned.
* @param {String} defaultLanguage The default language to be returned * @param {String} defaultLanguage The default language to be returned
* if the user language is not supported. * if the user language is not supported.
* @param {String} [probeLanguage] A language code to try to use, * @param {String} [probeLanguage] A language code to try to use,
* instead of the browser based autodetection. * instead of the browser based autodetection.
* @returns {String} The detected language code. * @returns {String} The detected language code.
* @example * @example
* alert( CKEDITOR.lang.detect( 'en' ) ); // e.g., in a German browser: "de" * alert( CKEDITOR.lang.detect( 'en' ) ); // e.g., in a German browser: "de"
*/ */
detect : function( defaultLanguage, probeLanguage ) detect : function( defaultLanguage, probeLanguage )
{ {
var languages = this.languages; var languages = this.languages;
probeLanguage = probeLanguage || navigator.userLanguage || navigator.language || defaultLanguage; probeLanguage = probeLanguage || navigator.userLanguage || navigator.language || defaultLanguage;
var parts = probeLanguage var parts = probeLanguage
.toLowerCase() .toLowerCase()
.match( /([a-z]+)(?:-([a-z]+))?/ ), .match( /([a-z]+)(?:-([a-z]+))?/ ),
lang = parts[1], lang = parts[1],
locale = parts[2]; locale = parts[2];
if ( languages[ lang + '-' + locale ] ) if ( languages[ lang + '-' + locale ] )
lang = lang + '-' + locale; lang = lang + '-' + locale;
else if ( !languages[ lang ] ) else if ( !languages[ lang ] )
lang = null; lang = null;
CKEDITOR.lang.detect = lang ? CKEDITOR.lang.detect = lang ?
function() { return lang; } : function() { return lang; } :
function( defaultLanguage ) { return defaultLanguage; }; function( defaultLanguage ) { return defaultLanguage; };
return lang || defaultLanguage; return lang || defaultLanguage;
} }
}; };
})(); })();

View File

@@ -1,240 +1,240 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.loader} objects, which is used to * @fileOverview Defines the {@link CKEDITOR.loader} objects, which is used to
* load core scripts and their dependencies from _source. * load core scripts and their dependencies from _source.
*/ */
if ( typeof CKEDITOR == 'undefined' ) if ( typeof CKEDITOR == 'undefined' )
CKEDITOR = {}; CKEDITOR = {};
if ( !CKEDITOR.loader ) if ( !CKEDITOR.loader )
{ {
/** /**
* Load core scripts and their dependencies from _source. * Load core scripts and their dependencies from _source.
* @namespace * @namespace
* @example * @example
*/ */
CKEDITOR.loader = (function() CKEDITOR.loader = (function()
{ {
// Table of script names and their dependencies. // Table of script names and their dependencies.
var scripts = var scripts =
{ {
'core/_bootstrap' : [ 'core/config', 'core/ckeditor', 'core/plugins', 'core/scriptloader', 'core/tools', /* The following are entries that we want to force loading at the end to avoid dependence recursion */ 'core/dom/comment', 'core/dom/elementpath', 'core/dom/text', 'core/dom/rangelist' ], 'core/_bootstrap' : [ 'core/config', 'core/ckeditor', 'core/plugins', 'core/scriptloader', 'core/tools', /* The following are entries that we want to force loading at the end to avoid dependence recursion */ 'core/dom/comment', 'core/dom/elementpath', 'core/dom/text', 'core/dom/rangelist' ],
'core/ckeditor' : [ 'core/ckeditor_basic', 'core/dom', 'core/dtd', 'core/dom/document', 'core/dom/element', 'core/editor', 'core/event', 'core/htmlparser', 'core/htmlparser/element', 'core/htmlparser/fragment', 'core/htmlparser/filter', 'core/htmlparser/basicwriter', 'core/tools' ], 'core/ckeditor' : [ 'core/ckeditor_basic', 'core/dom', 'core/dtd', 'core/dom/document', 'core/dom/element', 'core/editor', 'core/event', 'core/htmlparser', 'core/htmlparser/element', 'core/htmlparser/fragment', 'core/htmlparser/filter', 'core/htmlparser/basicwriter', 'core/tools' ],
'core/ckeditor_base' : [], 'core/ckeditor_base' : [],
'core/ckeditor_basic' : [ 'core/editor_basic', 'core/env', 'core/event' ], 'core/ckeditor_basic' : [ 'core/editor_basic', 'core/env', 'core/event' ],
'core/command' : [], 'core/command' : [],
'core/config' : [ 'core/ckeditor_base' ], 'core/config' : [ 'core/ckeditor_base' ],
'core/dom' : [], 'core/dom' : [],
'core/dom/comment' : [ 'core/dom/node' ], 'core/dom/comment' : [ 'core/dom/node' ],
'core/dom/document' : [ 'core/dom', 'core/dom/domobject', 'core/dom/window' ], 'core/dom/document' : [ 'core/dom', 'core/dom/domobject', 'core/dom/window' ],
'core/dom/documentfragment' : [ 'core/dom/element' ], 'core/dom/documentfragment' : [ 'core/dom/element' ],
'core/dom/element' : [ 'core/dom', 'core/dom/document', 'core/dom/domobject', 'core/dom/node', 'core/dom/nodelist', 'core/tools' ], 'core/dom/element' : [ 'core/dom', 'core/dom/document', 'core/dom/domobject', 'core/dom/node', 'core/dom/nodelist', 'core/tools' ],
'core/dom/elementpath' : [ 'core/dom/element' ], 'core/dom/elementpath' : [ 'core/dom/element' ],
'core/dom/event' : [], 'core/dom/event' : [],
'core/dom/node' : [ 'core/dom/domobject', 'core/tools' ], 'core/dom/node' : [ 'core/dom/domobject', 'core/tools' ],
'core/dom/nodelist' : [ 'core/dom/node' ], 'core/dom/nodelist' : [ 'core/dom/node' ],
'core/dom/domobject' : [ 'core/dom/event' ], 'core/dom/domobject' : [ 'core/dom/event' ],
'core/dom/range' : [ 'core/dom/document', 'core/dom/documentfragment', 'core/dom/element', 'core/dom/walker' ], 'core/dom/range' : [ 'core/dom/document', 'core/dom/documentfragment', 'core/dom/element', 'core/dom/walker' ],
'core/dom/rangelist' : [ 'core/dom/range' ], 'core/dom/rangelist' : [ 'core/dom/range' ],
'core/dom/text' : [ 'core/dom/node', 'core/dom/domobject' ], 'core/dom/text' : [ 'core/dom/node', 'core/dom/domobject' ],
'core/dom/walker' : [ 'core/dom/node' ], 'core/dom/walker' : [ 'core/dom/node' ],
'core/dom/window' : [ 'core/dom/domobject' ], 'core/dom/window' : [ 'core/dom/domobject' ],
'core/dtd' : [ 'core/tools' ], 'core/dtd' : [ 'core/tools' ],
'core/editor' : [ 'core/command', 'core/config', 'core/editor_basic', 'core/focusmanager', 'core/lang', 'core/plugins', 'core/skins', 'core/themes', 'core/tools', 'core/ui' ], 'core/editor' : [ 'core/command', 'core/config', 'core/editor_basic', 'core/focusmanager', 'core/lang', 'core/plugins', 'core/skins', 'core/themes', 'core/tools', 'core/ui' ],
'core/editor_basic' : [ 'core/event' ], 'core/editor_basic' : [ 'core/event' ],
'core/env' : [], 'core/env' : [],
'core/event' : [], 'core/event' : [],
'core/focusmanager' : [], 'core/focusmanager' : [],
'core/htmlparser' : [], 'core/htmlparser' : [],
'core/htmlparser/comment' : [ 'core/htmlparser' ], 'core/htmlparser/comment' : [ 'core/htmlparser' ],
'core/htmlparser/element' : [ 'core/htmlparser', 'core/htmlparser/fragment' ], 'core/htmlparser/element' : [ 'core/htmlparser', 'core/htmlparser/fragment' ],
'core/htmlparser/fragment' : [ 'core/htmlparser', 'core/htmlparser/comment', 'core/htmlparser/text', 'core/htmlparser/cdata' ], 'core/htmlparser/fragment' : [ 'core/htmlparser', 'core/htmlparser/comment', 'core/htmlparser/text', 'core/htmlparser/cdata' ],
'core/htmlparser/text' : [ 'core/htmlparser' ], 'core/htmlparser/text' : [ 'core/htmlparser' ],
'core/htmlparser/cdata' : [ 'core/htmlparser' ], 'core/htmlparser/cdata' : [ 'core/htmlparser' ],
'core/htmlparser/filter' : [ 'core/htmlparser' ], 'core/htmlparser/filter' : [ 'core/htmlparser' ],
'core/htmlparser/basicwriter': [ 'core/htmlparser' ], 'core/htmlparser/basicwriter': [ 'core/htmlparser' ],
'core/lang' : [], 'core/lang' : [],
'core/plugins' : [ 'core/resourcemanager' ], 'core/plugins' : [ 'core/resourcemanager' ],
'core/resourcemanager' : [ 'core/scriptloader', 'core/tools' ], 'core/resourcemanager' : [ 'core/scriptloader', 'core/tools' ],
'core/scriptloader' : [ 'core/dom/element', 'core/env' ], 'core/scriptloader' : [ 'core/dom/element', 'core/env' ],
'core/skins' : [ 'core/scriptloader' ], 'core/skins' : [ 'core/scriptloader' ],
'core/themes' : [ 'core/resourcemanager' ], 'core/themes' : [ 'core/resourcemanager' ],
'core/tools' : [ 'core/env' ], 'core/tools' : [ 'core/env' ],
'core/ui' : [] 'core/ui' : []
}; };
var basePath = (function() var basePath = (function()
{ {
// This is a copy of CKEDITOR.basePath, but requires the script having // This is a copy of CKEDITOR.basePath, but requires the script having
// "_source/core/loader.js". // "_source/core/loader.js".
if ( CKEDITOR && CKEDITOR.basePath ) if ( CKEDITOR && CKEDITOR.basePath )
return CKEDITOR.basePath; return CKEDITOR.basePath;
// Find out the editor directory path, based on its <script> tag. // Find out the editor directory path, based on its <script> tag.
var path = ''; var path = '';
var scripts = document.getElementsByTagName( 'script' ); var scripts = document.getElementsByTagName( 'script' );
for ( var i = 0 ; i < scripts.length ; i++ ) for ( var i = 0 ; i < scripts.length ; i++ )
{ {
var match = scripts[i].src.match( /(^|.*?[\\\/])(?:_source\/)?core\/loader.js(?:\?.*)?$/i ); var match = scripts[i].src.match( /(^|.*?[\\\/])(?:_source\/)?core\/loader.js(?:\?.*)?$/i );
if ( match ) if ( match )
{ {
path = match[1]; path = match[1];
break; break;
} }
} }
// In IE (only) the script.src string is the raw valued entered in the // In IE (only) the script.src string is the raw valued entered in the
// HTML. Other browsers return the full resolved URL instead. // HTML. Other browsers return the full resolved URL instead.
if ( path.indexOf('://') == -1 ) if ( path.indexOf('://') == -1 )
{ {
// Absolute path. // Absolute path.
if ( path.indexOf( '/' ) === 0 ) if ( path.indexOf( '/' ) === 0 )
path = location.href.match( /^.*?:\/\/[^\/]*/ )[0] + path; path = location.href.match( /^.*?:\/\/[^\/]*/ )[0] + path;
// Relative path. // Relative path.
else else
path = location.href.match( /^[^\?]*\// )[0] + path; path = location.href.match( /^[^\?]*\// )[0] + path;
} }
return path; return path;
})(); })();
var timestamp = 'C6HH5UF'; var timestamp = 'C6HH5UF';
var getUrl = function( resource ) var getUrl = function( resource )
{ {
if ( CKEDITOR && CKEDITOR.getUrl ) if ( CKEDITOR && CKEDITOR.getUrl )
return CKEDITOR.getUrl( resource ); return CKEDITOR.getUrl( resource );
return basePath + resource + return basePath + resource +
( resource.indexOf( '?' ) >= 0 ? '&' : '?' ) + ( resource.indexOf( '?' ) >= 0 ? '&' : '?' ) +
't=' + timestamp; 't=' + timestamp;
}; };
var pendingLoad = []; var pendingLoad = [];
/** @lends CKEDITOR.loader */ /** @lends CKEDITOR.loader */
return { return {
/** /**
* The list of loaded scripts in their loading order. * The list of loaded scripts in their loading order.
* @type Array * @type Array
* @example * @example
* // Alert the loaded script names. * // Alert the loaded script names.
* alert( <b>CKEDITOR.loader.loadedScripts</b> ); * alert( <b>CKEDITOR.loader.loadedScripts</b> );
*/ */
loadedScripts : [], loadedScripts : [],
loadPending : function() loadPending : function()
{ {
var scriptName = pendingLoad.shift(); var scriptName = pendingLoad.shift();
if ( !scriptName ) if ( !scriptName )
return; return;
var scriptSrc = getUrl( '_source/' + scriptName + '.js' ); var scriptSrc = getUrl( '_source/' + scriptName + '.js' );
var script = document.createElement( 'script' ); var script = document.createElement( 'script' );
script.type = 'text/javascript'; script.type = 'text/javascript';
script.src = scriptSrc; script.src = scriptSrc;
function onScriptLoaded() function onScriptLoaded()
{ {
// Append this script to the list of loaded scripts. // Append this script to the list of loaded scripts.
CKEDITOR.loader.loadedScripts.push( scriptName ); CKEDITOR.loader.loadedScripts.push( scriptName );
// Load the next. // Load the next.
CKEDITOR.loader.loadPending(); CKEDITOR.loader.loadPending();
} }
// We must guarantee the execution order of the scripts, so we // We must guarantee the execution order of the scripts, so we
// need to load them one by one. (#4145) // need to load them one by one. (#4145)
// The following if/else block has been taken from the scriptloader core code. // The following if/else block has been taken from the scriptloader core code.
if ( typeof(script.onreadystatechange) !== "undefined" ) if ( typeof(script.onreadystatechange) !== "undefined" )
{ {
/** @ignore */ /** @ignore */
script.onreadystatechange = function() script.onreadystatechange = function()
{ {
if ( script.readyState == 'loaded' || script.readyState == 'complete' ) if ( script.readyState == 'loaded' || script.readyState == 'complete' )
{ {
script.onreadystatechange = null; script.onreadystatechange = null;
onScriptLoaded(); onScriptLoaded();
} }
}; };
} }
else else
{ {
/** @ignore */ /** @ignore */
script.onload = function() script.onload = function()
{ {
// Some browsers, such as Safari, may call the onLoad function // Some browsers, such as Safari, may call the onLoad function
// immediately. Which will break the loading sequence. (#3661) // immediately. Which will break the loading sequence. (#3661)
setTimeout( function() { onScriptLoaded( scriptName ); }, 0 ); setTimeout( function() { onScriptLoaded( scriptName ); }, 0 );
}; };
} }
document.body.appendChild( script ); document.body.appendChild( script );
}, },
/** /**
* Loads a specific script, including its dependencies. This is not a * Loads a specific script, including its dependencies. This is not a
* synchronous loading, which means that the code to be loaded will * synchronous loading, which means that the code to be loaded will
* not necessarily be available after this call. * not necessarily be available after this call.
* @example * @example
* CKEDITOR.loader.load( 'core/dom/element' ); * CKEDITOR.loader.load( 'core/dom/element' );
*/ */
load : function( scriptName, defer ) load : function( scriptName, defer )
{ {
// Check if the script has already been loaded. // Check if the script has already been loaded.
if ( scriptName in this.loadedScripts ) if ( scriptName in this.loadedScripts )
return; return;
// Get the script dependencies list. // Get the script dependencies list.
var dependencies = scripts[ scriptName ]; var dependencies = scripts[ scriptName ];
if ( !dependencies ) if ( !dependencies )
throw 'The script name"' + scriptName + '" is not defined.'; throw 'The script name"' + scriptName + '" is not defined.';
// Mark the script as loaded, even before really loading it, to // Mark the script as loaded, even before really loading it, to
// avoid cross references recursion. // avoid cross references recursion.
this.loadedScripts[ scriptName ] = true; this.loadedScripts[ scriptName ] = true;
// Load all dependencies first. // Load all dependencies first.
for ( var i = 0 ; i < dependencies.length ; i++ ) for ( var i = 0 ; i < dependencies.length ; i++ )
this.load( dependencies[ i ], true ); this.load( dependencies[ i ], true );
var scriptSrc = getUrl( '_source/' + scriptName + '.js' ); var scriptSrc = getUrl( '_source/' + scriptName + '.js' );
// Append the <script> element to the DOM. // Append the <script> element to the DOM.
// If the page is fully loaded, we can't use document.write // If the page is fully loaded, we can't use document.write
// but if the script is run while the body is loading then it's safe to use it // but if the script is run while the body is loading then it's safe to use it
// Unfortunately, Firefox <3.6 doesn't support document.readyState, so it won't get this improvement // Unfortunately, Firefox <3.6 doesn't support document.readyState, so it won't get this improvement
if ( document.body && (!document.readyState || document.readyState == 'complete') ) if ( document.body && (!document.readyState || document.readyState == 'complete') )
{ {
pendingLoad.push( scriptName ); pendingLoad.push( scriptName );
if ( !defer ) if ( !defer )
this.loadPending(); this.loadPending();
} }
else else
{ {
// Append this script to the list of loaded scripts. // Append this script to the list of loaded scripts.
this.loadedScripts.push( scriptName ); this.loadedScripts.push( scriptName );
document.write( '<script src="' + scriptSrc + '" type="text/javascript"><\/script>' ); document.write( '<script src="' + scriptSrc + '" type="text/javascript"><\/script>' );
} }
} }
}; };
})(); })();
} }
// Check if any script has been defined for autoload. // Check if any script has been defined for autoload.
if ( CKEDITOR._autoLoad ) if ( CKEDITOR._autoLoad )
{ {
CKEDITOR.loader.load( CKEDITOR._autoLoad ); CKEDITOR.loader.load( CKEDITOR._autoLoad );
delete CKEDITOR._autoLoad; delete CKEDITOR._autoLoad;
} }

View File

@@ -1,83 +1,83 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the "virtual" {@link CKEDITOR.pluginDefinition} class, which * @fileOverview Defines the "virtual" {@link CKEDITOR.pluginDefinition} class, which
* contains the defintion of a plugin. This file is for documentation * contains the defintion of a plugin. This file is for documentation
* purposes only. * purposes only.
*/ */
/** /**
* (Virtual Class) Do not call this constructor. This class is not really part * (Virtual Class) Do not call this constructor. This class is not really part
* of the API. It just illustrates the features of plugin objects to be * of the API. It just illustrates the features of plugin objects to be
* passed to the {@link CKEDITOR.plugins.add} function. * passed to the {@link CKEDITOR.plugins.add} function.
* @name CKEDITOR.pluginDefinition * @name CKEDITOR.pluginDefinition
* @constructor * @constructor
* @example * @example
*/ */
/** /**
* A list of plugins that are required by this plugin. Note that this property * A list of plugins that are required by this plugin. Note that this property
* doesn't guarantee the loading order of the plugins. * doesn't guarantee the loading order of the plugins.
* @name CKEDITOR.pluginDefinition.prototype.requires * @name CKEDITOR.pluginDefinition.prototype.requires
* @type Array * @type Array
* @example * @example
* CKEDITOR.plugins.add( 'sample', * CKEDITOR.plugins.add( 'sample',
* { * {
* requires : [ 'button', 'selection' ] * requires : [ 'button', 'selection' ]
* }); * });
*/ */
/** /**
* A list of language files available for this plugin. These files are stored inside * A list of language files available for this plugin. These files are stored inside
* the "lang" directory, which is inside the plugin directory, follow the name * the "lang" directory, which is inside the plugin directory, follow the name
* pattern of "langCode.js", and contain a language definition created with {@link CKEDITOR.pluginDefinition#setLang}. * pattern of "langCode.js", and contain a language definition created with {@link CKEDITOR.pluginDefinition#setLang}.
* While the plugin is being loaded, the editor checks this list to see if * While the plugin is being loaded, the editor checks this list to see if
* a language file of the current editor language ({@link CKEDITOR.editor#langCode}) * a language file of the current editor language ({@link CKEDITOR.editor#langCode})
* is available, and if so, loads it. Otherwise, the file represented by the first list item * is available, and if so, loads it. Otherwise, the file represented by the first list item
* in the list is loaded. * in the list is loaded.
* @name CKEDITOR.pluginDefinition.prototype.lang * @name CKEDITOR.pluginDefinition.prototype.lang
* @type Array * @type Array
* @example * @example
* CKEDITOR.plugins.add( 'sample', * CKEDITOR.plugins.add( 'sample',
* { * {
* lang : [ 'en', 'fr' ] * lang : [ 'en', 'fr' ]
* }); * });
*/ */
/** /**
* Function called on initialization of every editor instance created in the * Function called on initialization of every editor instance created in the
* page before the init() call task. The beforeInit function will be called for * page before the init() call task. The beforeInit function will be called for
* all plugins, after that the init function is called for all of them. This * all plugins, after that the init function is called for all of them. This
* feature makes it possible to initialize things that could be used in the * feature makes it possible to initialize things that could be used in the
* init function of other plugins. * init function of other plugins.
* @name CKEDITOR.pluginDefinition.prototype.beforeInit * @name CKEDITOR.pluginDefinition.prototype.beforeInit
* @function * @function
* @param {CKEDITOR.editor} editor The editor instance being initialized. * @param {CKEDITOR.editor} editor The editor instance being initialized.
* @example * @example
* CKEDITOR.plugins.add( 'sample', * CKEDITOR.plugins.add( 'sample',
* { * {
* beforeInit : function( editor ) * beforeInit : function( editor )
* { * {
* alert( 'Editor "' + editor.name + '" is to be initialized!' ); * alert( 'Editor "' + editor.name + '" is to be initialized!' );
* } * }
* }); * });
*/ */
/** /**
* Function called on initialization of every editor instance created in the * Function called on initialization of every editor instance created in the
* page. * page.
* @name CKEDITOR.pluginDefinition.prototype.init * @name CKEDITOR.pluginDefinition.prototype.init
* @function * @function
* @param {CKEDITOR.editor} editor The editor instance being initialized. * @param {CKEDITOR.editor} editor The editor instance being initialized.
* @example * @example
* CKEDITOR.plugins.add( 'sample', * CKEDITOR.plugins.add( 'sample',
* { * {
* init : function( editor ) * init : function( editor )
* { * {
* alert( 'Editor "' + editor.name + '" is being initialized!' ); * alert( 'Editor "' + editor.name + '" is being initialized!' );
* } * }
* }); * });
*/ */

View File

@@ -1,103 +1,103 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.plugins} object, which is used to * @fileOverview Defines the {@link CKEDITOR.plugins} object, which is used to
* manage plugins registration and loading. * manage plugins registration and loading.
*/ */
/** /**
* Manages plugins registration and loading. * Manages plugins registration and loading.
* @namespace * @namespace
* @augments CKEDITOR.resourceManager * @augments CKEDITOR.resourceManager
* @example * @example
*/ */
CKEDITOR.plugins = new CKEDITOR.resourceManager( CKEDITOR.plugins = new CKEDITOR.resourceManager(
'_source/' + // @Packager.RemoveLine '_source/' + // @Packager.RemoveLine
'plugins/', 'plugin' ); 'plugins/', 'plugin' );
// PACKAGER_RENAME( CKEDITOR.plugins ) // PACKAGER_RENAME( CKEDITOR.plugins )
CKEDITOR.plugins.load = CKEDITOR.tools.override( CKEDITOR.plugins.load, function( originalLoad ) CKEDITOR.plugins.load = CKEDITOR.tools.override( CKEDITOR.plugins.load, function( originalLoad )
{ {
return function( name, callback, scope ) return function( name, callback, scope )
{ {
var allPlugins = {}; var allPlugins = {};
var loadPlugins = function( names ) var loadPlugins = function( names )
{ {
originalLoad.call( this, names, function( plugins ) originalLoad.call( this, names, function( plugins )
{ {
CKEDITOR.tools.extend( allPlugins, plugins ); CKEDITOR.tools.extend( allPlugins, plugins );
var requiredPlugins = []; var requiredPlugins = [];
for ( var pluginName in plugins ) for ( var pluginName in plugins )
{ {
var plugin = plugins[ pluginName ], var plugin = plugins[ pluginName ],
requires = plugin && plugin.requires; requires = plugin && plugin.requires;
if ( requires ) if ( requires )
{ {
for ( var i = 0 ; i < requires.length ; i++ ) for ( var i = 0 ; i < requires.length ; i++ )
{ {
if ( !allPlugins[ requires[ i ] ] ) if ( !allPlugins[ requires[ i ] ] )
requiredPlugins.push( requires[ i ] ); requiredPlugins.push( requires[ i ] );
} }
} }
} }
if ( requiredPlugins.length ) if ( requiredPlugins.length )
loadPlugins.call( this, requiredPlugins ); loadPlugins.call( this, requiredPlugins );
else else
{ {
// Call the "onLoad" function for all plugins. // Call the "onLoad" function for all plugins.
for ( pluginName in allPlugins ) for ( pluginName in allPlugins )
{ {
plugin = allPlugins[ pluginName ]; plugin = allPlugins[ pluginName ];
if ( plugin.onLoad && !plugin.onLoad._called ) if ( plugin.onLoad && !plugin.onLoad._called )
{ {
plugin.onLoad(); plugin.onLoad();
plugin.onLoad._called = 1; plugin.onLoad._called = 1;
} }
} }
// Call the callback. // Call the callback.
if ( callback ) if ( callback )
callback.call( scope || window, allPlugins ); callback.call( scope || window, allPlugins );
} }
} }
, this); , this);
}; };
loadPlugins.call( this, name ); loadPlugins.call( this, name );
}; };
}); });
/** /**
* Loads a specific language file, or auto detect it. A callback is * Loads a specific language file, or auto detect it. A callback is
* then called when the file gets loaded. * then called when the file gets loaded.
* @param {String} pluginName The name of the plugin to which the provided translation * @param {String} pluginName The name of the plugin to which the provided translation
* should be attached. * should be attached.
* @param {String} languageCode The code of the language translation provided. * @param {String} languageCode The code of the language translation provided.
* @param {Object} languageEntries An object that contains pairs of label and * @param {Object} languageEntries An object that contains pairs of label and
* the respective translation. * the respective translation.
* @example * @example
* CKEDITOR.plugins.setLang( 'myPlugin', 'en', { * CKEDITOR.plugins.setLang( 'myPlugin', 'en', {
* title : 'My plugin', * title : 'My plugin',
* selectOption : 'Please select an option' * selectOption : 'Please select an option'
* } ); * } );
*/ */
CKEDITOR.plugins.setLang = function( pluginName, languageCode, languageEntries ) CKEDITOR.plugins.setLang = function( pluginName, languageCode, languageEntries )
{ {
var plugin = this.get( pluginName ), var plugin = this.get( pluginName ),
pluginLangEntries = plugin.langEntries || ( plugin.langEntries = {} ), pluginLangEntries = plugin.langEntries || ( plugin.langEntries = {} ),
pluginLang = plugin.lang || ( plugin.lang = [] ); pluginLang = plugin.lang || ( plugin.lang = [] );
if ( CKEDITOR.tools.indexOf( pluginLang, languageCode ) == -1 ) if ( CKEDITOR.tools.indexOf( pluginLang, languageCode ) == -1 )
pluginLang.push( languageCode ); pluginLang.push( languageCode );
pluginLangEntries[ languageCode ] = languageEntries; pluginLangEntries[ languageCode ] = languageEntries;
}; };

View File

@@ -1,238 +1,238 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.resourceManager} class, which is * @fileOverview Defines the {@link CKEDITOR.resourceManager} class, which is
* the base for resource managers, like plugins and themes. * the base for resource managers, like plugins and themes.
*/ */
/** /**
* Base class for resource managers, like plugins and themes. This class is not * Base class for resource managers, like plugins and themes. This class is not
* intended to be used out of the CKEditor core code. * intended to be used out of the CKEditor core code.
* @param {String} basePath The path for the resources folder. * @param {String} basePath The path for the resources folder.
* @param {String} fileName The name used for resource files. * @param {String} fileName The name used for resource files.
* @namespace * @namespace
* @example * @example
*/ */
CKEDITOR.resourceManager = function( basePath, fileName ) CKEDITOR.resourceManager = function( basePath, fileName )
{ {
/** /**
* The base directory containing all resources. * The base directory containing all resources.
* @name CKEDITOR.resourceManager.prototype.basePath * @name CKEDITOR.resourceManager.prototype.basePath
* @type String * @type String
* @example * @example
*/ */
this.basePath = basePath; this.basePath = basePath;
/** /**
* The name used for resource files. * The name used for resource files.
* @name CKEDITOR.resourceManager.prototype.fileName * @name CKEDITOR.resourceManager.prototype.fileName
* @type String * @type String
* @example * @example
*/ */
this.fileName = fileName; this.fileName = fileName;
/** /**
* Contains references to all resources that have already been registered * Contains references to all resources that have already been registered
* with {@link #add}. * with {@link #add}.
* @name CKEDITOR.resourceManager.prototype.registered * @name CKEDITOR.resourceManager.prototype.registered
* @type Object * @type Object
* @example * @example
*/ */
this.registered = {}; this.registered = {};
/** /**
* Contains references to all resources that have already been loaded * Contains references to all resources that have already been loaded
* with {@link #load}. * with {@link #load}.
* @name CKEDITOR.resourceManager.prototype.loaded * @name CKEDITOR.resourceManager.prototype.loaded
* @type Object * @type Object
* @example * @example
*/ */
this.loaded = {}; this.loaded = {};
/** /**
* Contains references to all resources that have already been registered * Contains references to all resources that have already been registered
* with {@link #addExternal}. * with {@link #addExternal}.
* @name CKEDITOR.resourceManager.prototype.externals * @name CKEDITOR.resourceManager.prototype.externals
* @type Object * @type Object
* @example * @example
*/ */
this.externals = {}; this.externals = {};
/** /**
* @private * @private
*/ */
this._ = this._ =
{ {
// List of callbacks waiting for plugins to be loaded. // List of callbacks waiting for plugins to be loaded.
waitingList : {} waitingList : {}
}; };
}; };
CKEDITOR.resourceManager.prototype = CKEDITOR.resourceManager.prototype =
{ {
/** /**
* Registers a resource. * Registers a resource.
* @param {String} name The resource name. * @param {String} name The resource name.
* @param {Object} [definition] The resource definition. * @param {Object} [definition] The resource definition.
* @example * @example
* CKEDITOR.plugins.add( 'sample', { ... plugin definition ... } ); * CKEDITOR.plugins.add( 'sample', { ... plugin definition ... } );
* @see CKEDITOR.pluginDefinition * @see CKEDITOR.pluginDefinition
*/ */
add : function( name, definition ) add : function( name, definition )
{ {
if ( this.registered[ name ] ) if ( this.registered[ name ] )
throw '[CKEDITOR.resourceManager.add] The resource name "' + name + '" is already registered.'; throw '[CKEDITOR.resourceManager.add] The resource name "' + name + '" is already registered.';
CKEDITOR.fire( name + CKEDITOR.tools.capitalize( this.fileName ) + 'Ready', CKEDITOR.fire( name + CKEDITOR.tools.capitalize( this.fileName ) + 'Ready',
this.registered[ name ] = definition || {} ); this.registered[ name ] = definition || {} );
}, },
/** /**
* Gets the definition of a specific resource. * Gets the definition of a specific resource.
* @param {String} name The resource name. * @param {String} name The resource name.
* @type Object * @type Object
* @example * @example
* var definition = <b>CKEDITOR.plugins.get( 'sample' )</b>; * var definition = <b>CKEDITOR.plugins.get( 'sample' )</b>;
*/ */
get : function( name ) get : function( name )
{ {
return this.registered[ name ] || null; return this.registered[ name ] || null;
}, },
/** /**
* Get the folder path for a specific loaded resource. * Get the folder path for a specific loaded resource.
* @param {String} name The resource name. * @param {String} name The resource name.
* @type String * @type String
* @example * @example
* alert( <b>CKEDITOR.plugins.getPath( 'sample' )</b> ); // "&lt;editor path&gt;/plugins/sample/" * alert( <b>CKEDITOR.plugins.getPath( 'sample' )</b> ); // "&lt;editor path&gt;/plugins/sample/"
*/ */
getPath : function( name ) getPath : function( name )
{ {
var external = this.externals[ name ]; var external = this.externals[ name ];
return CKEDITOR.getUrl( ( external && external.dir ) || this.basePath + name + '/' ); return CKEDITOR.getUrl( ( external && external.dir ) || this.basePath + name + '/' );
}, },
/** /**
* Get the file path for a specific loaded resource. * Get the file path for a specific loaded resource.
* @param {String} name The resource name. * @param {String} name The resource name.
* @type String * @type String
* @example * @example
* alert( <b>CKEDITOR.plugins.getFilePath( 'sample' )</b> ); // "&lt;editor path&gt;/plugins/sample/plugin.js" * alert( <b>CKEDITOR.plugins.getFilePath( 'sample' )</b> ); // "&lt;editor path&gt;/plugins/sample/plugin.js"
*/ */
getFilePath : function( name ) getFilePath : function( name )
{ {
var external = this.externals[ name ]; var external = this.externals[ name ];
return CKEDITOR.getUrl( return CKEDITOR.getUrl(
this.getPath( name ) + this.getPath( name ) +
( ( external && ( typeof external.file == 'string' ) ) ? external.file : this.fileName + '.js' ) ); ( ( external && ( typeof external.file == 'string' ) ) ? external.file : this.fileName + '.js' ) );
}, },
/** /**
* Registers one or more resources to be loaded from an external path * Registers one or more resources to be loaded from an external path
* instead of the core base path. * instead of the core base path.
* @param {String} names The resource names, separated by commas. * @param {String} names The resource names, separated by commas.
* @param {String} path The path of the folder containing the resource. * @param {String} path The path of the folder containing the resource.
* @param {String} [fileName] The resource file name. If not provided, the * @param {String} [fileName] The resource file name. If not provided, the
* default name is used; If provided with a empty string, will implicitly indicates that {@param path} * default name is used; If provided with a empty string, will implicitly indicates that {@param path}
* is already the full path. * is already the full path.
* @example * @example
* // Loads a plugin from '/myplugin/samples/plugin.js'. * // Loads a plugin from '/myplugin/samples/plugin.js'.
* CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/' ); * CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/' );
* @example * @example
* // Loads a plugin from '/myplugin/samples/my_plugin.js'. * // Loads a plugin from '/myplugin/samples/my_plugin.js'.
* CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/', 'my_plugin.js' ); * CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/', 'my_plugin.js' );
* @example * @example
* // Loads a plugin from '/myplugin/samples/my_plugin.js'. * // Loads a plugin from '/myplugin/samples/my_plugin.js'.
* CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/my_plugin.js', '' ); * CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/my_plugin.js', '' );
*/ */
addExternal : function( names, path, fileName ) addExternal : function( names, path, fileName )
{ {
names = names.split( ',' ); names = names.split( ',' );
for ( var i = 0 ; i < names.length ; i++ ) for ( var i = 0 ; i < names.length ; i++ )
{ {
var name = names[ i ]; var name = names[ i ];
this.externals[ name ] = this.externals[ name ] =
{ {
dir : path, dir : path,
file : fileName file : fileName
}; };
} }
}, },
/** /**
* Loads one or more resources. * Loads one or more resources.
* @param {String|Array} name The name of the resource to load. It may be a * @param {String|Array} name The name of the resource to load. It may be a
* string with a single resource name, or an array with several names. * string with a single resource name, or an array with several names.
* @param {Function} callback A function to be called when all resources * @param {Function} callback A function to be called when all resources
* are loaded. The callback will receive an array containing all * are loaded. The callback will receive an array containing all
* loaded names. * loaded names.
* @param {Object} [scope] The scope object to be used for the callback * @param {Object} [scope] The scope object to be used for the callback
* call. * call.
* @example * @example
* <b>CKEDITOR.plugins.load</b>( 'myplugin', function( plugins ) * <b>CKEDITOR.plugins.load</b>( 'myplugin', function( plugins )
* { * {
* alert( plugins['myplugin'] ); // "object" * alert( plugins['myplugin'] ); // "object"
* }); * });
*/ */
load : function( names, callback, scope ) load : function( names, callback, scope )
{ {
// Ensure that we have an array of names. // Ensure that we have an array of names.
if ( !CKEDITOR.tools.isArray( names ) ) if ( !CKEDITOR.tools.isArray( names ) )
names = names ? [ names ] : []; names = names ? [ names ] : [];
var loaded = this.loaded, var loaded = this.loaded,
registered = this.registered, registered = this.registered,
urls = [], urls = [],
urlsNames = {}, urlsNames = {},
resources = {}; resources = {};
// Loop through all names. // Loop through all names.
for ( var i = 0 ; i < names.length ; i++ ) for ( var i = 0 ; i < names.length ; i++ )
{ {
var name = names[ i ]; var name = names[ i ];
if ( !name ) if ( !name )
continue; continue;
// If not available yet. // If not available yet.
if ( !loaded[ name ] && !registered[ name ] ) if ( !loaded[ name ] && !registered[ name ] )
{ {
var url = this.getFilePath( name ); var url = this.getFilePath( name );
urls.push( url ); urls.push( url );
if ( !( url in urlsNames ) ) if ( !( url in urlsNames ) )
urlsNames[ url ] = []; urlsNames[ url ] = [];
urlsNames[ url ].push( name ); urlsNames[ url ].push( name );
} }
else else
resources[ name ] = this.get( name ); resources[ name ] = this.get( name );
} }
CKEDITOR.scriptLoader.load( urls, function( completed, failed ) CKEDITOR.scriptLoader.load( urls, function( completed, failed )
{ {
if ( failed.length ) if ( failed.length )
{ {
throw '[CKEDITOR.resourceManager.load] Resource name "' + urlsNames[ failed[ 0 ] ].join( ',' ) throw '[CKEDITOR.resourceManager.load] Resource name "' + urlsNames[ failed[ 0 ] ].join( ',' )
+ '" was not found at "' + failed[ 0 ] + '".'; + '" was not found at "' + failed[ 0 ] + '".';
} }
for ( var i = 0 ; i < completed.length ; i++ ) for ( var i = 0 ; i < completed.length ; i++ )
{ {
var nameList = urlsNames[ completed[ i ] ]; var nameList = urlsNames[ completed[ i ] ];
for ( var j = 0 ; j < nameList.length ; j++ ) for ( var j = 0 ; j < nameList.length ; j++ )
{ {
var name = nameList[ j ]; var name = nameList[ j ];
resources[ name ] = this.get( name ); resources[ name ] = this.get( name );
loaded[ name ] = 1; loaded[ name ] = 1;
} }
} }
callback.call( scope, resources ); callback.call( scope, resources );
} }
, this); , this);
} }
}; };

View File

@@ -1,180 +1,180 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.scriptLoader} object, used to load scripts * @fileOverview Defines the {@link CKEDITOR.scriptLoader} object, used to load scripts
* asynchronously. * asynchronously.
*/ */
/** /**
* Load scripts asynchronously. * Load scripts asynchronously.
* @namespace * @namespace
* @example * @example
*/ */
CKEDITOR.scriptLoader = (function() CKEDITOR.scriptLoader = (function()
{ {
var uniqueScripts = {}, var uniqueScripts = {},
waitingList = {}; waitingList = {};
return /** @lends CKEDITOR.scriptLoader */ { return /** @lends CKEDITOR.scriptLoader */ {
/** /**
* Loads one or more external script checking if not already loaded * Loads one or more external script checking if not already loaded
* previously by this function. * previously by this function.
* @param {String|Array} scriptUrl One or more URLs pointing to the * @param {String|Array} scriptUrl One or more URLs pointing to the
* scripts to be loaded. * scripts to be loaded.
* @param {Function} [callback] A function to be called when the script * @param {Function} [callback] A function to be called when the script
* is loaded and executed. If a string is passed to "scriptUrl", a * is loaded and executed. If a string is passed to "scriptUrl", a
* boolean parameter is passed to the callback, indicating the * boolean parameter is passed to the callback, indicating the
* success of the load. If an array is passed instead, two array * success of the load. If an array is passed instead, two array
* parameters are passed to the callback; the first contains the * parameters are passed to the callback; the first contains the
* URLs that have been properly loaded, and the second the failed * URLs that have been properly loaded, and the second the failed
* ones. * ones.
* @param {Object} [scope] The scope ("this" reference) to be used for * @param {Object} [scope] The scope ("this" reference) to be used for
* the callback call. Default to {@link CKEDITOR}. * the callback call. Default to {@link CKEDITOR}.
* @param {Boolean} [showBusy] Changes the cursor of the document while * @param {Boolean} [showBusy] Changes the cursor of the document while
+ * the script is loaded. + * the script is loaded.
* @example * @example
* CKEDITOR.scriptLoader.load( '/myscript.js' ); * CKEDITOR.scriptLoader.load( '/myscript.js' );
* @example * @example
* CKEDITOR.scriptLoader.load( '/myscript.js', function( success ) * CKEDITOR.scriptLoader.load( '/myscript.js', function( success )
* { * {
* // Alerts "true" if the script has been properly loaded. * // Alerts "true" if the script has been properly loaded.
* // HTTP error 404 should return "false". * // HTTP error 404 should return "false".
* alert( success ); * alert( success );
* }); * });
* @example * @example
* CKEDITOR.scriptLoader.load( [ '/myscript1.js', '/myscript2.js' ], function( completed, failed ) * CKEDITOR.scriptLoader.load( [ '/myscript1.js', '/myscript2.js' ], function( completed, failed )
* { * {
* alert( 'Number of scripts loaded: ' + completed.length ); * alert( 'Number of scripts loaded: ' + completed.length );
* alert( 'Number of failures: ' + failed.length ); * alert( 'Number of failures: ' + failed.length );
* }); * });
*/ */
load : function( scriptUrl, callback, scope, showBusy ) load : function( scriptUrl, callback, scope, showBusy )
{ {
var isString = ( typeof scriptUrl == 'string' ); var isString = ( typeof scriptUrl == 'string' );
if ( isString ) if ( isString )
scriptUrl = [ scriptUrl ]; scriptUrl = [ scriptUrl ];
if ( !scope ) if ( !scope )
scope = CKEDITOR; scope = CKEDITOR;
var scriptCount = scriptUrl.length, var scriptCount = scriptUrl.length,
completed = [], completed = [],
failed = []; failed = [];
var doCallback = function( success ) var doCallback = function( success )
{ {
if ( callback ) if ( callback )
{ {
if ( isString ) if ( isString )
callback.call( scope, success ); callback.call( scope, success );
else else
callback.call( scope, completed, failed ); callback.call( scope, completed, failed );
} }
}; };
if ( scriptCount === 0 ) if ( scriptCount === 0 )
{ {
doCallback( true ); doCallback( true );
return; return;
} }
var checkLoaded = function( url, success ) var checkLoaded = function( url, success )
{ {
( success ? completed : failed ).push( url ); ( success ? completed : failed ).push( url );
if ( --scriptCount <= 0 ) if ( --scriptCount <= 0 )
{ {
showBusy && CKEDITOR.document.getDocumentElement().removeStyle( 'cursor' ); showBusy && CKEDITOR.document.getDocumentElement().removeStyle( 'cursor' );
doCallback( success ); doCallback( success );
} }
}; };
var onLoad = function( url, success ) var onLoad = function( url, success )
{ {
// Mark this script as loaded. // Mark this script as loaded.
uniqueScripts[ url ] = 1; uniqueScripts[ url ] = 1;
// Get the list of callback checks waiting for this file. // Get the list of callback checks waiting for this file.
var waitingInfo = waitingList[ url ]; var waitingInfo = waitingList[ url ];
delete waitingList[ url ]; delete waitingList[ url ];
// Check all callbacks waiting for this file. // Check all callbacks waiting for this file.
for ( var i = 0 ; i < waitingInfo.length ; i++ ) for ( var i = 0 ; i < waitingInfo.length ; i++ )
waitingInfo[ i ]( url, success ); waitingInfo[ i ]( url, success );
}; };
var loadScript = function( url ) var loadScript = function( url )
{ {
if ( uniqueScripts[ url ] ) if ( uniqueScripts[ url ] )
{ {
checkLoaded( url, true ); checkLoaded( url, true );
return; return;
} }
var waitingInfo = waitingList[ url ] || ( waitingList[ url ] = [] ); var waitingInfo = waitingList[ url ] || ( waitingList[ url ] = [] );
waitingInfo.push( checkLoaded ); waitingInfo.push( checkLoaded );
// Load it only for the first request. // Load it only for the first request.
if ( waitingInfo.length > 1 ) if ( waitingInfo.length > 1 )
return; return;
// Create the <script> element. // Create the <script> element.
var script = new CKEDITOR.dom.element( 'script' ); var script = new CKEDITOR.dom.element( 'script' );
script.setAttributes( { script.setAttributes( {
type : 'text/javascript', type : 'text/javascript',
src : url } ); src : url } );
if ( callback ) if ( callback )
{ {
if ( CKEDITOR.env.ie ) if ( CKEDITOR.env.ie )
{ {
// FIXME: For IE, we are not able to return false on error (like 404). // FIXME: For IE, we are not able to return false on error (like 404).
/** @ignore */ /** @ignore */
script.$.onreadystatechange = function () script.$.onreadystatechange = function ()
{ {
if ( script.$.readyState == 'loaded' || script.$.readyState == 'complete' ) if ( script.$.readyState == 'loaded' || script.$.readyState == 'complete' )
{ {
script.$.onreadystatechange = null; script.$.onreadystatechange = null;
onLoad( url, true ); onLoad( url, true );
} }
}; };
} }
else else
{ {
/** @ignore */ /** @ignore */
script.$.onload = function() script.$.onload = function()
{ {
// Some browsers, such as Safari, may call the onLoad function // Some browsers, such as Safari, may call the onLoad function
// immediately. Which will break the loading sequence. (#3661) // immediately. Which will break the loading sequence. (#3661)
setTimeout( function() { onLoad( url, true ); }, 0 ); setTimeout( function() { onLoad( url, true ); }, 0 );
}; };
// FIXME: Opera and Safari will not fire onerror. // FIXME: Opera and Safari will not fire onerror.
/** @ignore */ /** @ignore */
script.$.onerror = function() script.$.onerror = function()
{ {
onLoad( url, false ); onLoad( url, false );
}; };
} }
} }
// Append it to <head>. // Append it to <head>.
script.appendTo( CKEDITOR.document.getHead() ); script.appendTo( CKEDITOR.document.getHead() );
CKEDITOR.fire( 'download', url ); // @Packager.RemoveLine CKEDITOR.fire( 'download', url ); // @Packager.RemoveLine
}; };
showBusy && CKEDITOR.document.getDocumentElement().setStyle( 'cursor', 'wait' ); showBusy && CKEDITOR.document.getDocumentElement().setStyle( 'cursor', 'wait' );
for ( var i = 0 ; i < scriptCount ; i++ ) for ( var i = 0 ; i < scriptCount ; i++ )
{ {
loadScript( scriptUrl[ i ] ); loadScript( scriptUrl[ i ] );
} }
} }
}; };
})(); })();

View File

@@ -1,184 +1,184 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.skins} object, which is used to * @fileOverview Defines the {@link CKEDITOR.skins} object, which is used to
* manage skins loading. * manage skins loading.
*/ */
/** /**
* Manages skins loading. * Manages skins loading.
* @namespace * @namespace
* @example * @example
*/ */
CKEDITOR.skins = (function() CKEDITOR.skins = (function()
{ {
// Holds the list of loaded skins. // Holds the list of loaded skins.
var loaded = {}, var loaded = {},
paths = {}; paths = {};
var loadPart = function( editor, skinName, part, callback ) var loadPart = function( editor, skinName, part, callback )
{ {
// Get the skin definition. // Get the skin definition.
var skinDefinition = loaded[ skinName ]; var skinDefinition = loaded[ skinName ];
if ( !editor.skin ) if ( !editor.skin )
{ {
editor.skin = skinDefinition; editor.skin = skinDefinition;
// Trigger init function if any. // Trigger init function if any.
if ( skinDefinition.init ) if ( skinDefinition.init )
skinDefinition.init( editor ); skinDefinition.init( editor );
} }
var appendSkinPath = function( fileNames ) var appendSkinPath = function( fileNames )
{ {
for ( var n = 0 ; n < fileNames.length ; n++ ) for ( var n = 0 ; n < fileNames.length ; n++ )
{ {
fileNames[ n ] = CKEDITOR.getUrl( paths[ skinName ] + fileNames[ n ] ); fileNames[ n ] = CKEDITOR.getUrl( paths[ skinName ] + fileNames[ n ] );
} }
}; };
function fixCSSTextRelativePath( cssStyleText, baseUrl ) function fixCSSTextRelativePath( cssStyleText, baseUrl )
{ {
return cssStyleText.replace( /url\s*\(([\s'"]*)(.*?)([\s"']*)\)/g, return cssStyleText.replace( /url\s*\(([\s'"]*)(.*?)([\s"']*)\)/g,
function( match, opener, path, closer ) function( match, opener, path, closer )
{ {
if ( /^\/|^\w?:/.test( path ) ) if ( /^\/|^\w?:/.test( path ) )
return match; return match;
else else
return 'url(' + baseUrl + opener + path + closer + ')'; return 'url(' + baseUrl + opener + path + closer + ')';
} ); } );
} }
// Get the part definition. // Get the part definition.
part = skinDefinition[ part ]; part = skinDefinition[ part ];
var partIsLoaded = !part || !!part._isLoaded; var partIsLoaded = !part || !!part._isLoaded;
// Call the callback immediately if already loaded. // Call the callback immediately if already loaded.
if ( partIsLoaded ) if ( partIsLoaded )
callback && callback(); callback && callback();
else else
{ {
// Put the callback in a queue. // Put the callback in a queue.
var pending = part._pending || ( part._pending = [] ); var pending = part._pending || ( part._pending = [] );
pending.push( callback ); pending.push( callback );
// We may have more than one skin part load request. Just the first // We may have more than one skin part load request. Just the first
// one must do the loading job. // one must do the loading job.
if ( pending.length > 1 ) if ( pending.length > 1 )
return; return;
// Check whether the "css" and "js" properties have been defined // Check whether the "css" and "js" properties have been defined
// for that part. // for that part.
var cssIsLoaded = !part.css || !part.css.length, var cssIsLoaded = !part.css || !part.css.length,
jsIsLoaded = !part.js || !part.js.length; jsIsLoaded = !part.js || !part.js.length;
// This is the function that will trigger the callback calls on // This is the function that will trigger the callback calls on
// load. // load.
var checkIsLoaded = function() var checkIsLoaded = function()
{ {
if ( cssIsLoaded && jsIsLoaded ) if ( cssIsLoaded && jsIsLoaded )
{ {
// Mark the part as loaded. // Mark the part as loaded.
part._isLoaded = 1; part._isLoaded = 1;
// Call all pending callbacks. // Call all pending callbacks.
for ( var i = 0 ; i < pending.length ; i++ ) for ( var i = 0 ; i < pending.length ; i++ )
{ {
if ( pending[ i ] ) if ( pending[ i ] )
pending[ i ](); pending[ i ]();
} }
} }
}; };
// Load the "css" pieces. // Load the "css" pieces.
if ( !cssIsLoaded ) if ( !cssIsLoaded )
{ {
var cssPart = part.css; var cssPart = part.css;
if ( CKEDITOR.tools.isArray( cssPart ) ) if ( CKEDITOR.tools.isArray( cssPart ) )
{ {
appendSkinPath( cssPart ); appendSkinPath( cssPart );
for ( var c = 0 ; c < cssPart.length ; c++ ) for ( var c = 0 ; c < cssPart.length ; c++ )
CKEDITOR.document.appendStyleSheet( cssPart[ c ] ); CKEDITOR.document.appendStyleSheet( cssPart[ c ] );
} }
else else
{ {
cssPart = fixCSSTextRelativePath( cssPart = fixCSSTextRelativePath(
cssPart, CKEDITOR.getUrl( paths[ skinName ] ) ); cssPart, CKEDITOR.getUrl( paths[ skinName ] ) );
// Processing Inline CSS part. // Processing Inline CSS part.
CKEDITOR.document.appendStyleText( cssPart ); CKEDITOR.document.appendStyleText( cssPart );
} }
part.css = cssPart; part.css = cssPart;
cssIsLoaded = 1; cssIsLoaded = 1;
} }
// Load the "js" pieces. // Load the "js" pieces.
if ( !jsIsLoaded ) if ( !jsIsLoaded )
{ {
appendSkinPath( part.js ); appendSkinPath( part.js );
CKEDITOR.scriptLoader.load( part.js, function() CKEDITOR.scriptLoader.load( part.js, function()
{ {
jsIsLoaded = 1; jsIsLoaded = 1;
checkIsLoaded(); checkIsLoaded();
}); });
} }
// We may have nothing to load, so check it immediately. // We may have nothing to load, so check it immediately.
checkIsLoaded(); checkIsLoaded();
} }
}; };
return /** @lends CKEDITOR.skins */ { return /** @lends CKEDITOR.skins */ {
/** /**
* Registers a skin definition. * Registers a skin definition.
* @param {String} skinName The skin name. * @param {String} skinName The skin name.
* @param {Object} skinDefinition The skin definition. * @param {Object} skinDefinition The skin definition.
* @example * @example
*/ */
add : function( skinName, skinDefinition ) add : function( skinName, skinDefinition )
{ {
loaded[ skinName ] = skinDefinition; loaded[ skinName ] = skinDefinition;
skinDefinition.skinPath = paths[ skinName ] skinDefinition.skinPath = paths[ skinName ]
|| ( paths[ skinName ] = || ( paths[ skinName ] =
CKEDITOR.getUrl( CKEDITOR.getUrl(
'_source/' + // @Packager.RemoveLine '_source/' + // @Packager.RemoveLine
'skins/' + skinName + '/' ) ); 'skins/' + skinName + '/' ) );
}, },
/** /**
* Loads a skin part. Skins are defined in parts, which are basically * Loads a skin part. Skins are defined in parts, which are basically
* separated CSS files. This function is mainly used by the core code and * separated CSS files. This function is mainly used by the core code and
* should not have much use out of it. * should not have much use out of it.
* @param {String} skinName The name of the skin to be loaded. * @param {String} skinName The name of the skin to be loaded.
* @param {String} skinPart The skin part to be loaded. Common skin parts * @param {String} skinPart The skin part to be loaded. Common skin parts
* are "editor" and "dialog". * are "editor" and "dialog".
* @param {Function} [callback] A function to be called once the skin * @param {Function} [callback] A function to be called once the skin
* part files are loaded. * part files are loaded.
* @example * @example
*/ */
load : function( editor, skinPart, callback ) load : function( editor, skinPart, callback )
{ {
var skinName = editor.skinName, var skinName = editor.skinName,
skinPath = editor.skinPath; skinPath = editor.skinPath;
if ( loaded[ skinName ] ) if ( loaded[ skinName ] )
loadPart( editor, skinName, skinPart, callback ); loadPart( editor, skinName, skinPart, callback );
else else
{ {
paths[ skinName ] = skinPath; paths[ skinName ] = skinPath;
CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( skinPath + 'skin.js' ), function() CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( skinPath + 'skin.js' ), function()
{ {
loadPart( editor, skinName, skinPart, callback ); loadPart( editor, skinName, skinPart, callback );
}); });
} }
} }
}; };
})(); })();

View File

@@ -1,19 +1,19 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* @fileOverview Defines the {@link CKEDITOR.themes} object, which is used to * @fileOverview Defines the {@link CKEDITOR.themes} object, which is used to
* manage themes registration and loading. * manage themes registration and loading.
*/ */
/** /**
* Manages themes registration and loading. * Manages themes registration and loading.
* @namespace * @namespace
* @augments CKEDITOR.resourceManager * @augments CKEDITOR.resourceManager
* @example * @example
*/ */
CKEDITOR.themes = new CKEDITOR.resourceManager( CKEDITOR.themes = new CKEDITOR.resourceManager(
'_source/'+ // @Packager.RemoveLine '_source/'+ // @Packager.RemoveLine
'themes/', 'theme' ); 'themes/', 'theme' );

File diff suppressed because it is too large Load Diff

View File

@@ -1,128 +1,128 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
/** /**
* Contains UI features related to an editor instance. * Contains UI features related to an editor instance.
* @constructor * @constructor
* @param {CKEDITOR.editor} editor The editor instance. * @param {CKEDITOR.editor} editor The editor instance.
* @example * @example
*/ */
CKEDITOR.ui = function( editor ) CKEDITOR.ui = function( editor )
{ {
if ( editor.ui ) if ( editor.ui )
return editor.ui; return editor.ui;
/** /**
* Object used to hold private stuff. * Object used to hold private stuff.
* @private * @private
*/ */
this._ = this._ =
{ {
handlers : {}, handlers : {},
items : {}, items : {},
editor : editor editor : editor
}; };
return this; return this;
}; };
// PACKAGER_RENAME( CKEDITOR.ui ) // PACKAGER_RENAME( CKEDITOR.ui )
CKEDITOR.ui.prototype = CKEDITOR.ui.prototype =
{ {
/** /**
* Adds a UI item to the items collection. These items can be later used in * Adds a UI item to the items collection. These items can be later used in
* the interface. * the interface.
* @param {String} name The UI item name. * @param {String} name The UI item name.
* @param {Object} type The item type. * @param {Object} type The item type.
* @param {Object} definition The item definition. The properties of this * @param {Object} definition The item definition. The properties of this
* object depend on the item type. * object depend on the item type.
* @example * @example
* // Add a new button named "MyBold". * // Add a new button named "MyBold".
* editorInstance.ui.add( 'MyBold', CKEDITOR.UI_BUTTON, * editorInstance.ui.add( 'MyBold', CKEDITOR.UI_BUTTON,
* { * {
* label : 'My Bold', * label : 'My Bold',
* command : 'bold' * command : 'bold'
* }); * });
*/ */
add : function( name, type, definition ) add : function( name, type, definition )
{ {
this._.items[ name ] = this._.items[ name ] =
{ {
type : type, type : type,
// The name of {@link CKEDITOR.command} which associate with this UI. // The name of {@link CKEDITOR.command} which associate with this UI.
command : definition.command || null, command : definition.command || null,
args : Array.prototype.slice.call( arguments, 2 ) args : Array.prototype.slice.call( arguments, 2 )
}; };
}, },
/** /**
* Gets a UI object. * Gets a UI object.
* @param {String} name The UI item hame. * @param {String} name The UI item hame.
* @example * @example
*/ */
create : function( name ) create : function( name )
{ {
var item = this._.items[ name ], var item = this._.items[ name ],
handler = item && this._.handlers[ item.type ], handler = item && this._.handlers[ item.type ],
command = item && item.command && this._.editor.getCommand( item.command ); command = item && item.command && this._.editor.getCommand( item.command );
var result = handler && handler.create.apply( this, item.args ); var result = handler && handler.create.apply( this, item.args );
// Allow overrides from skin ui definitions.. // Allow overrides from skin ui definitions..
item && ( result = CKEDITOR.tools.extend( result, this._.editor.skin[ item.type ], true ) ); item && ( result = CKEDITOR.tools.extend( result, this._.editor.skin[ item.type ], true ) );
// Add reference inside command object. // Add reference inside command object.
if ( command ) if ( command )
command.uiItems.push( result ); command.uiItems.push( result );
return result; return result;
}, },
/** /**
* Adds a handler for a UI item type. The handler is responsible for * Adds a handler for a UI item type. The handler is responsible for
* transforming UI item definitions in UI objects. * transforming UI item definitions in UI objects.
* @param {Object} type The item type. * @param {Object} type The item type.
* @param {Object} handler The handler definition. * @param {Object} handler The handler definition.
* @example * @example
*/ */
addHandler : function( type, handler ) addHandler : function( type, handler )
{ {
this._.handlers[ type ] = handler; this._.handlers[ type ] = handler;
} }
}; };
CKEDITOR.event.implementOn( CKEDITOR.ui ); CKEDITOR.event.implementOn( CKEDITOR.ui );
/** /**
* (Virtual Class) Do not call this constructor. This class is not really part * (Virtual Class) Do not call this constructor. This class is not really part
* of the API. It just illustrates the features of hanlder objects to be * of the API. It just illustrates the features of hanlder objects to be
* passed to the {@link CKEDITOR.ui.prototype.addHandler} function. * passed to the {@link CKEDITOR.ui.prototype.addHandler} function.
* @name CKEDITOR.ui.handlerDefinition * @name CKEDITOR.ui.handlerDefinition
* @constructor * @constructor
* @example * @example
*/ */
/** /**
* Transforms an item definition into an UI item object. * Transforms an item definition into an UI item object.
* @name CKEDITOR.handlerDefinition.prototype.create * @name CKEDITOR.handlerDefinition.prototype.create
* @function * @function
* @param {Object} definition The item definition. * @param {Object} definition The item definition.
* @example * @example
* editorInstance.ui.addHandler( CKEDITOR.UI_BUTTON, * editorInstance.ui.addHandler( CKEDITOR.UI_BUTTON,
* { * {
* create : function( definition ) * create : function( definition )
* { * {
* return new CKEDITOR.ui.button( definition ); * return new CKEDITOR.ui.button( definition );
* } * }
* }); * });
*/ */
/** /**
* Internal event fired when a new UI element is ready * Internal event fired when a new UI element is ready
* @name CKEDITOR.ui#ready * @name CKEDITOR.ui#ready
* @event * @event
* @param {Object} element The new element * @param {Object} element The new element
*/ */

View File

@@ -1,84 +1,84 @@
/* /*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
var CKEDITOR_LANGS = (function() var CKEDITOR_LANGS = (function()
{ {
var langs = var langs =
{ {
af : 'Afrikaans', af : 'Afrikaans',
ar : 'Arabic', ar : 'Arabic',
bg : 'Bulgarian', bg : 'Bulgarian',
bn : 'Bengali/Bangla', bn : 'Bengali/Bangla',
bs : 'Bosnian', bs : 'Bosnian',
ca : 'Catalan', ca : 'Catalan',
cs : 'Czech', cs : 'Czech',
cy : 'Welsh', cy : 'Welsh',
da : 'Danish', da : 'Danish',
de : 'German', de : 'German',
el : 'Greek', el : 'Greek',
en : 'English', en : 'English',
'en-au' : 'English (Australia)', 'en-au' : 'English (Australia)',
'en-ca' : 'English (Canadian)', 'en-ca' : 'English (Canadian)',
'en-gb' : 'English (United Kingdom)', 'en-gb' : 'English (United Kingdom)',
eo : 'Esperanto', eo : 'Esperanto',
es : 'Spanish', es : 'Spanish',
et : 'Estonian', et : 'Estonian',
eu : 'Basque', eu : 'Basque',
fa : 'Persian', fa : 'Persian',
fi : 'Finnish', fi : 'Finnish',
fo : 'Faroese', fo : 'Faroese',
fr : 'French', fr : 'French',
'fr-ca' : 'French (Canada)', 'fr-ca' : 'French (Canada)',
gl : 'Galician', gl : 'Galician',
gu : 'Gujarati', gu : 'Gujarati',
he : 'Hebrew', he : 'Hebrew',
hi : 'Hindi', hi : 'Hindi',
hr : 'Croatian', hr : 'Croatian',
hu : 'Hungarian', hu : 'Hungarian',
is : 'Icelandic', is : 'Icelandic',
it : 'Italian', it : 'Italian',
ja : 'Japanese', ja : 'Japanese',
ka : 'Georgian', ka : 'Georgian',
km : 'Khmer', km : 'Khmer',
ko : 'Korean', ko : 'Korean',
lt : 'Lithuanian', lt : 'Lithuanian',
lv : 'Latvian', lv : 'Latvian',
mn : 'Mongolian', mn : 'Mongolian',
ms : 'Malay', ms : 'Malay',
nb : 'Norwegian Bokmal', nb : 'Norwegian Bokmal',
nl : 'Dutch', nl : 'Dutch',
no : 'Norwegian', no : 'Norwegian',
pl : 'Polish', pl : 'Polish',
pt : 'Portuguese (Portugal)', pt : 'Portuguese (Portugal)',
'pt-br' : 'Portuguese (Brazil)', 'pt-br' : 'Portuguese (Brazil)',
ro : 'Romanian', ro : 'Romanian',
ru : 'Russian', ru : 'Russian',
sk : 'Slovak', sk : 'Slovak',
sl : 'Slovenian', sl : 'Slovenian',
sr : 'Serbian (Cyrillic)', sr : 'Serbian (Cyrillic)',
'sr-latn' : 'Serbian (Latin)', 'sr-latn' : 'Serbian (Latin)',
sv : 'Swedish', sv : 'Swedish',
th : 'Thai', th : 'Thai',
tr : 'Turkish', tr : 'Turkish',
uk : 'Ukrainian', uk : 'Ukrainian',
vi : 'Vietnamese', vi : 'Vietnamese',
zh : 'Chinese Traditional', zh : 'Chinese Traditional',
'zh-cn' : 'Chinese Simplified' 'zh-cn' : 'Chinese Simplified'
}; };
var langsArray = []; var langsArray = [];
for ( var code in langs ) for ( var code in langs )
{ {
langsArray.push( { code : code, name : langs[ code ] } ); langsArray.push( { code : code, name : langs[ code ] } );
} }
langsArray.sort( function( a, b ) langsArray.sort( function( a, b )
{ {
return ( a.name < b.name ) ? -1 : 1; return ( a.name < b.name ) ? -1 : 1;
}); });
return langsArray; return langsArray;
})(); })();

View File

@@ -1,64 +1,64 @@
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
af.js Found: 548 Missing: 29 af.js Found: 548 Missing: 29
ar.js Found: 470 Missing: 107 ar.js Found: 470 Missing: 107
bg.js Found: 394 Missing: 183 bg.js Found: 394 Missing: 183
bn.js Found: 292 Missing: 285 bn.js Found: 292 Missing: 285
bs.js Found: 175 Missing: 402 bs.js Found: 175 Missing: 402
ca.js Found: 549 Missing: 28 ca.js Found: 549 Missing: 28
cs.js Found: 577 Missing: 0 cs.js Found: 577 Missing: 0
cy.js Found: 575 Missing: 2 cy.js Found: 575 Missing: 2
da.js Found: 575 Missing: 2 da.js Found: 575 Missing: 2
de.js Found: 575 Missing: 2 de.js Found: 575 Missing: 2
el.js Found: 391 Missing: 186 el.js Found: 391 Missing: 186
en-au.js Found: 347 Missing: 230 en-au.js Found: 347 Missing: 230
en-ca.js Found: 345 Missing: 232 en-ca.js Found: 345 Missing: 232
en-gb.js Found: 517 Missing: 60 en-gb.js Found: 517 Missing: 60
eo.js Found: 577 Missing: 0 eo.js Found: 577 Missing: 0
es.js Found: 575 Missing: 2 es.js Found: 575 Missing: 2
et.js Found: 577 Missing: 0 et.js Found: 577 Missing: 0
eu.js Found: 417 Missing: 160 eu.js Found: 417 Missing: 160
fa.js Found: 575 Missing: 2 fa.js Found: 575 Missing: 2
fi.js Found: 575 Missing: 2 fi.js Found: 575 Missing: 2
fo.js Found: 575 Missing: 2 fo.js Found: 575 Missing: 2
fr-ca.js Found: 319 Missing: 258 fr-ca.js Found: 319 Missing: 258
fr.js Found: 575 Missing: 2 fr.js Found: 575 Missing: 2
gl.js Found: 292 Missing: 285 gl.js Found: 292 Missing: 285
gu.js Found: 575 Missing: 2 gu.js Found: 575 Missing: 2
he.js Found: 575 Missing: 2 he.js Found: 575 Missing: 2
hi.js Found: 327 Missing: 250 hi.js Found: 327 Missing: 250
hr.js Found: 575 Missing: 2 hr.js Found: 575 Missing: 2
hu.js Found: 572 Missing: 5 hu.js Found: 572 Missing: 5
id.js Found: 1 Missing: 576 id.js Found: 1 Missing: 576
is.js Found: 326 Missing: 251 is.js Found: 326 Missing: 251
it.js Found: 577 Missing: 0 it.js Found: 577 Missing: 0
ja.js Found: 493 Missing: 84 ja.js Found: 493 Missing: 84
ka.js Found: 568 Missing: 9 ka.js Found: 568 Missing: 9
km.js Found: 286 Missing: 291 km.js Found: 286 Missing: 291
ko.js Found: 304 Missing: 273 ko.js Found: 304 Missing: 273
lt.js Found: 575 Missing: 2 lt.js Found: 575 Missing: 2
lv.js Found: 294 Missing: 283 lv.js Found: 294 Missing: 283
mk.js Found: 0 Missing: 577 mk.js Found: 0 Missing: 577
mn.js Found: 320 Missing: 257 mn.js Found: 320 Missing: 257
ms.js Found: 276 Missing: 301 ms.js Found: 276 Missing: 301
nb.js Found: 577 Missing: 0 nb.js Found: 577 Missing: 0
nl.js Found: 575 Missing: 2 nl.js Found: 575 Missing: 2
no.js Found: 577 Missing: 0 no.js Found: 577 Missing: 0
pl.js Found: 575 Missing: 2 pl.js Found: 575 Missing: 2
pt-br.js Found: 577 Missing: 0 pt-br.js Found: 577 Missing: 0
pt.js Found: 326 Missing: 251 pt.js Found: 326 Missing: 251
ro.js Found: 432 Missing: 145 ro.js Found: 432 Missing: 145
ru.js Found: 575 Missing: 2 ru.js Found: 575 Missing: 2
sk.js Found: 364 Missing: 213 sk.js Found: 364 Missing: 213
sl.js Found: 426 Missing: 151 sl.js Found: 426 Missing: 151
sr-latn.js Found: 287 Missing: 290 sr-latn.js Found: 287 Missing: 290
sr.js Found: 286 Missing: 291 sr.js Found: 286 Missing: 291
sv.js Found: 550 Missing: 27 sv.js Found: 550 Missing: 27
th.js Found: 298 Missing: 279 th.js Found: 298 Missing: 279
tr.js Found: 575 Missing: 2 tr.js Found: 575 Missing: 2
ug.js Found: 572 Missing: 5 ug.js Found: 572 Missing: 5
uk.js Found: 575 Missing: 2 uk.js Found: 575 Missing: 2
vi.js Found: 577 Missing: 0 vi.js Found: 577 Missing: 0
zh-cn.js Found: 577 Missing: 0 zh-cn.js Found: 577 Missing: 0
zh.js Found: 433 Missing: 144 zh.js Found: 433 Missing: 144

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More